Browse Source

Merge branch 'develop-evmcc' into pr-jit

cl-refactor
Paweł Bylica 10 years ago
parent
commit
d70ec1c442
  1. 13
      CMakeLists.txt
  2. 2
      eth/CMakeLists.txt
  3. 7
      evmcc/CMakeLists.txt
  4. 2
      evmcc/evmcc.cpp
  5. 1
      evmcc/test/arith/arith_bnot.evm
  6. 14
      evmcc/test/arith/arith_bnot.lll
  7. 1
      evmcc/test/ext/store_delete.evm
  8. 9
      evmcc/test/ext/store_delete.lll
  9. 1
      evmcc/test/jump/jumpi_at_the_end.evm
  10. 1
      evmcc/test/jump/jumpi_at_the_end.lll
  11. 90
      evmcc/test/vmtests/vmPerformanceTest.json
  12. 41
      evmcc/test/vmtests/vm_jump.json
  13. 2
      exp/CMakeLists.txt
  14. 3
      libevm/VMFace.cpp
  15. 44
      libevmjit/Arith256.cpp
  16. 4
      libevmjit/BasicBlock.cpp
  17. 7
      libevmjit/CMakeLists.txt
  18. 81
      libevmjit/Compiler.cpp
  19. 7
      libevmjit/ExecutionEngine.cpp
  20. 91
      libevmjit/Ext.cpp
  21. 18
      libevmjit/GasMeter.cpp
  22. 37
      libevmjit/Memory.cpp
  23. 3
      libevmjit/Runtime.h
  24. 34
      libevmjit/Stack.cpp
  25. 2
      libevmjit/Stack.h
  26. 10
      libevmjit/Type.cpp
  27. 2
      libevmjit/Type.h
  28. 4
      libevmjit/VM.cpp
  29. 2
      neth/CMakeLists.txt
  30. 9
      test/CMakeLists.txt
  31. 2
      windows/LLVM.props

13
CMakeLists.txt

@ -15,6 +15,7 @@ function(createDefaultCacheConfig)
set(LANGUAGES OFF CACHE BOOL "Limit build to Serpent/LLL tools")
set(VMTRACE OFF CACHE BOOL "VM tracing and run-time checks (useful for cross-implementation VM debugging)")
set(PARANOIA OFF CACHE BOOL "Additional run-time checks")
set(EVMJIT OFF CACHE BOOL "Build a just-in-time compiler for EVM code (requires LLVM)")
endfunction()
@ -39,6 +40,14 @@ function(configureProject)
message(FATAL_ERROR "VM tracing requires debug.")
endif ()
endif ()
if (EVMJIT)
if (LANGUAGES)
message(FATAL_ERROR "Unset LANGUAGES to build EVMJIT")
else()
add_definitions(-DETH_EVMJIT)
endif()
endif()
endfunction()
@ -75,7 +84,7 @@ cmake_policy(SET CMP0015 NEW)
createDefaultCacheConfig()
configureProject()
message("-- LANGUAGES: ${LANGUAGES}; VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}")
message("-- LANGUAGES: ${LANGUAGES}; VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}; EVMJIT: ${EVMJIT}")
# Default TARGET_PLATFORM to "linux".
@ -158,7 +167,7 @@ if (NOT LANGUAGES)
endif()
endif()
if (EVMCC)
if (EVMJIT)
add_subdirectory(libevmjit)
add_subdirectory(evmcc)
endif()

2
eth/CMakeLists.txt

@ -15,7 +15,7 @@ target_link_libraries(${EXECUTABLE} webthree)
target_link_libraries(${EXECUTABLE} secp256k1)
target_link_libraries(${EXECUTABLE} gmp)
if(EVMCC)
if(EVMJIT)
target_link_libraries(${EXECUTABLE} evmjit)
endif()

7
evmcc/CMakeLists.txt

@ -25,8 +25,6 @@ if ("${TARGET_PLATFORM}" STREQUAL "w64")
target_link_libraries(${EXECUTABLE} iphlpapi)
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s)
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
elseif (UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
else ()
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
@ -42,13 +40,12 @@ message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
llvm_map_components_to_libnames(llvm_libs core support mcjit x86asmparser x86codegen)
target_link_libraries(evmcc ${llvm_libs})
# llvm_map_components_to_libnames(llvm_libs core support mcjit x86asmparser x86codegen)
# target_link_libraries(evmcc ${llvm_libs})
# end of LLVM specific commands
install( TARGETS ${EXECUTABLE} DESTINATION bin )
cmake_policy(SET CMP0015 NEW)

2
evmcc/evmcc.cpp

@ -8,8 +8,6 @@
#include <boost/algorithm/string.hpp>
#include <llvm/Support/raw_os_ostream.h>
#include <libdevcore/Common.h>
#include <libdevcore/CommonIO.h>
#include <libevmface/Instruction.h>

1
evmcc/test/arith/arith_bnot.evm

@ -0,0 +1 @@
6201e2406000546000530960005460206000f2

14
evmcc/test/arith/arith_bnot.lll

@ -0,0 +1,14 @@
(asm
123456
0
MSTORE
0
MLOAD
BNOT
0
MSTORE
32
0
RETURN
)

1
evmcc/test/ext/store_delete.evm

@ -0,0 +1 @@
6104d26063576000606357

9
evmcc/test/ext/store_delete.lll

@ -0,0 +1,9 @@
(asm
1234
99
SSTORE
0
99
SSTORE
)

1
evmcc/test/jump/jumpi_at_the_end.evm

@ -0,0 +1 @@
600a6000545d6000536001900380600054600659

1
evmcc/test/jump/jumpi_at_the_end.lll

@ -0,0 +1 @@
(asm 10 0 MSTORE JUMPDEST 0 MLOAD 1 SWAP1 SUB DUP1 0 MSTORE 6 JUMPI)

90
evmcc/test/vmtests/vmPerformanceTest.json

@ -1,5 +1,47 @@
{
"for100000" : {
"mulmodloop" : {
"callcreates" : [ ],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x60015d68010000000000000000908060010115600358",
"data" : "0x",
"gas" : "1000000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "0",
"out" : "0x0",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x60015d68010000000000000000908060010115600358",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x60015d68010000000000000000908060010115600358",
"nonce" : "0",
"storage" : { }
}
}
},
"for-1e06" : {
"callcreates" : [ ],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
@ -40,7 +82,7 @@
}
},
"recloop" : {
"recloop0x40000" : {
"callcreates" : [ ],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
@ -166,4 +208,48 @@
}
}
},
"jumptable100" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "10000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x6127105d600190038060000e6104615961001b600160005458005d610026600260005458005d610031600360005458005d61003c600460005458005d610047600560005458005d610052600660005458005d61005d600760005458005d610068600860005458005d610073600960005458005d61007e600a60005458005d610089600b60005458005d610094600c60005458005d61009f600d60005458005d6100aa600e60005458005d6100b5600f60005458005d6100c0601060005458005d6100cb601160005458005d6100d6601260005458005d6100e1601360005458005d6100ec601460005458005d6100f7601560005458005d610102601660005458005d61010d601760005458005d610118601860005458005d610123601960005458005d61012e601a60005458005d610139601b60005458005d610144601c60005458005d61014f601d60005458005d61015a601e60005458005d610165601f60005458005d610170602060005458005d61017b602160005458005d610186602260005458005d610191602360005458005d61019c602460005458005d6101a7602560005458005d6101b2602660005458005d6101bd602760005458005d6101c8602860005458005d6101d3602960005458005d6101de602a60005458005d6101e9602b60005458005d6101f4602c60005458005d6101ff602d60005458005d61020a602e60005458005d610215602f60005458005d610220603060005458005d61022b603160005458005d610236603260005458005d610241603360005458005d61024c603460005458005d610257603560005458005d610262603660005458005d61026d603760005458005d610278603860005458005d610283603960005458005d61028e603a60005458005d610299603b60005458005d6102a4603c60005458005d6102af603d60005458005d6102ba603e60005458005d6102c5603f60005458005d6102d0604060005458005d6102db604160005458005d6102e6604260005458005d6102f1604360005458005d6102fc604460005458005d610307604560005458005d610312604660005458005d61031d604760005458005d610328604860005458005d610333604960005458005d61033e604a60005458005d610349604b60005458005d610354604c60005458005d61035f604d60005458005d61036a604e60005458005d610375604f60005458005d610380605060005458005d61038b605160005458005d610396605260005458005d6103a1605360005458005d6103ac605460005458005d6103b7605560005458005d6103c2605660005458005d6103cd605760005458005d6103d8605860005458005d6103e3605960005458005d6103ee605a60005458005d6103f9605b60005458005d610404605c60005458005d61040f605d60005458005d61041a605e60005458005d610425605f60005458005d610430606060005458005d61043b606160005458005d610446606260005458005d610451606360005458005d61045c606460005458005d610004585d60206000f2",
"data" : "0x",
"gas" : "10000000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "4900496",
"out" : "0x0000000000000000000000000000000000000000000000000000000000000064",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x6127105d600190038060000e6104615961001b600160005458005d610026600260005458005d610031600360005458005d61003c600460005458005d610047600560005458005d610052600660005458005d61005d600760005458005d610068600860005458005d610073600960005458005d61007e600a60005458005d610089600b60005458005d610094600c60005458005d61009f600d60005458005d6100aa600e60005458005d6100b5600f60005458005d6100c0601060005458005d6100cb601160005458005d6100d6601260005458005d6100e1601360005458005d6100ec601460005458005d6100f7601560005458005d610102601660005458005d61010d601760005458005d610118601860005458005d610123601960005458005d61012e601a60005458005d610139601b60005458005d610144601c60005458005d61014f601d60005458005d61015a601e60005458005d610165601f60005458005d610170602060005458005d61017b602160005458005d610186602260005458005d610191602360005458005d61019c602460005458005d6101a7602560005458005d6101b2602660005458005d6101bd602760005458005d6101c8602860005458005d6101d3602960005458005d6101de602a60005458005d6101e9602b60005458005d6101f4602c60005458005d6101ff602d60005458005d61020a602e60005458005d610215602f60005458005d610220603060005458005d61022b603160005458005d610236603260005458005d610241603360005458005d61024c603460005458005d610257603560005458005d610262603660005458005d61026d603760005458005d610278603860005458005d610283603960005458005d61028e603a60005458005d610299603b60005458005d6102a4603c60005458005d6102af603d60005458005d6102ba603e60005458005d6102c5603f60005458005d6102d0604060005458005d6102db604160005458005d6102e6604260005458005d6102f1604360005458005d6102fc604460005458005d610307604560005458005d610312604660005458005d61031d604760005458005d610328604860005458005d610333604960005458005d61033e604a60005458005d610349604b60005458005d610354604c60005458005d61035f604d60005458005d61036a604e60005458005d610375604f60005458005d610380605060005458005d61038b605160005458005d610396605260005458005d6103a1605360005458005d6103ac605460005458005d6103b7605560005458005d6103c2605660005458005d6103cd605760005458005d6103d8605860005458005d6103e3605960005458005d6103ee605a60005458005d6103f9605b60005458005d610404605c60005458005d61040f605d60005458005d61041a605e60005458005d610425605f60005458005d610430606060005458005d61043b606160005458005d610446606260005458005d610451606360005458005d61045c606460005458005d610004585d60206000f2",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x6127105d600190038060000e6104615961001b600160005458005d610026600260005458005d610031600360005458005d61003c600460005458005d610047600560005458005d610052600660005458005d61005d600760005458005d610068600860005458005d610073600960005458005d61007e600a60005458005d610089600b60005458005d610094600c60005458005d61009f600d60005458005d6100aa600e60005458005d6100b5600f60005458005d6100c0601060005458005d6100cb601160005458005d6100d6601260005458005d6100e1601360005458005d6100ec601460005458005d6100f7601560005458005d610102601660005458005d61010d601760005458005d610118601860005458005d610123601960005458005d61012e601a60005458005d610139601b60005458005d610144601c60005458005d61014f601d60005458005d61015a601e60005458005d610165601f60005458005d610170602060005458005d61017b602160005458005d610186602260005458005d610191602360005458005d61019c602460005458005d6101a7602560005458005d6101b2602660005458005d6101bd602760005458005d6101c8602860005458005d6101d3602960005458005d6101de602a60005458005d6101e9602b60005458005d6101f4602c60005458005d6101ff602d60005458005d61020a602e60005458005d610215602f60005458005d610220603060005458005d61022b603160005458005d610236603260005458005d610241603360005458005d61024c603460005458005d610257603560005458005d610262603660005458005d61026d603760005458005d610278603860005458005d610283603960005458005d61028e603a60005458005d610299603b60005458005d6102a4603c60005458005d6102af603d60005458005d6102ba603e60005458005d6102c5603f60005458005d6102d0604060005458005d6102db604160005458005d6102e6604260005458005d6102f1604360005458005d6102fc604460005458005d610307604560005458005d610312604660005458005d61031d604760005458005d610328604860005458005d610333604960005458005d61033e604a60005458005d610349604b60005458005d610354604c60005458005d61035f604d60005458005d61036a604e60005458005d610375604f60005458005d610380605060005458005d61038b605160005458005d610396605260005458005d6103a1605360005458005d6103ac605460005458005d6103b7605560005458005d6103c2605660005458005d6103cd605760005458005d6103d8605860005458005d6103e3605960005458005d6103ee605a60005458005d6103f9605b60005458005d610404605c60005458005d61040f605d60005458005d61041a605e60005458005d610425605f60005458005d610430606060005458005d61043b606160005458005d610446606260005458005d610451606360005458005d61045c606460005458005d610004585d60206000f2",
"nonce" : "0",
"storage" : {
}
}
}
},
}

41
evmcc/test/vmtests/vm_jump.json

@ -0,0 +1,41 @@
{
"jumpi_at_the_end" : {
"callcreates" : [ ],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "10000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "(asm 10 0 MSTORE JUMPDEST 0 MLOAD 1 SWAP1 SUB DUP1 0 MSTORE 6 JUMPI)",
"data" : "0x",
"gas" : "1000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "895",
"out" : "0x0",
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "(asm 10 0 MSTORE JUMPDEST 0 MLOAD 1 SWAP1 SUB DUP1 0 MSTORE 6 JUMPI)",
"nonce" : "0",
"storage" : {}
}
},
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "(asm 10 0 MSTORE JUMPDEST 0 MLOAD 1 SWAP1 SUB DUP1 0 MSTORE 6 JUMPI)",
"nonce" : "0",
"storage" : {}
}
}
}
}

2
exp/CMakeLists.txt

@ -17,7 +17,7 @@ target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS})
endif()
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS})
if(EVMCC)
if(EVMJIT)
target_link_libraries(${EXECUTABLE} evmjit)
endif()

3
libevm/VMFace.cpp

@ -25,9 +25,10 @@ using namespace dev::eth;
std::unique_ptr<VMFace> VMFace::create(VMFace::Kind _kind, u256 _gas)
{
std::unique_ptr<VMFace> vm;
#if ETH_JIT
#if ETH_EVMJIT
vm.reset(_kind == Kind::JIT ? static_cast<VMFace*>(new jit::VM) : new VM);
#else
(void) _kind; // suppress unused var warning
vm.reset(new VM);
#endif
vm->reset(_gas);

44
libevmjit/Arith256.cpp

@ -101,58 +101,58 @@ llvm::Value* Arith256::mulmod(llvm::Value* _arg1, llvm::Value* _arg2, llvm::Valu
extern "C"
{
using namespace dev::eth::jit;
using namespace dev::eth::jit;
EXPORT void arith_mul(i256* _arg1, i256* _arg2, i256* _result)
{
EXPORT void arith_mul(i256* _arg1, i256* _arg2, i256* _result)
{
dev::u256 arg1 = llvm2eth(*_arg1);
dev::u256 arg2 = llvm2eth(*_arg2);
*_result = eth2llvm(arg1 * arg2);
}
}
EXPORT void arith_div(i256* _arg1, i256* _arg2, i256* _result)
{
EXPORT void arith_div(i256* _arg1, i256* _arg2, i256* _result)
{
dev::u256 arg1 = llvm2eth(*_arg1);
dev::u256 arg2 = llvm2eth(*_arg2);
*_result = eth2llvm(arg2 == 0 ? arg2 : arg1 / arg2);
}
}
EXPORT void arith_mod(i256* _arg1, i256* _arg2, i256* _result)
{
EXPORT void arith_mod(i256* _arg1, i256* _arg2, i256* _result)
{
dev::u256 arg1 = llvm2eth(*_arg1);
dev::u256 arg2 = llvm2eth(*_arg2);
*_result = eth2llvm(arg2 == 0 ? arg2 : arg1 % arg2);
}
}
EXPORT void arith_sdiv(i256* _arg1, i256* _arg2, i256* _result)
{
EXPORT void arith_sdiv(i256* _arg1, i256* _arg2, i256* _result)
{
dev::u256 arg1 = llvm2eth(*_arg1);
dev::u256 arg2 = llvm2eth(*_arg2);
*_result = eth2llvm(arg2 == 0 ? arg2 : dev::s2u(dev::u2s(arg1) / dev::u2s(arg2)));
}
}
EXPORT void arith_smod(i256* _arg1, i256* _arg2, i256* _result)
{
EXPORT void arith_smod(i256* _arg1, i256* _arg2, i256* _result)
{
dev::u256 arg1 = llvm2eth(*_arg1);
dev::u256 arg2 = llvm2eth(*_arg2);
*_result = eth2llvm(arg2 == 0 ? arg2 : dev::s2u(dev::u2s(arg1) % dev::u2s(arg2)));
}
}
EXPORT void arith_mulmod(i256* _arg1, i256* _arg2, i256* _arg3, i256* _result)
{
EXPORT void arith_mulmod(i256* _arg1, i256* _arg2, i256* _arg3, i256* _result)
{
dev::u256 arg1 = llvm2eth(*_arg1);
dev::u256 arg2 = llvm2eth(*_arg2);
dev::u256 arg3 = llvm2eth(*_arg3);
*_result = eth2llvm(dev::u256((dev::bigint(arg1) * dev::bigint(arg2)) % arg3));
}
}
EXPORT void arith_addmod(i256* _arg1, i256* _arg2, i256* _arg3, i256* _result)
{
EXPORT void arith_addmod(i256* _arg1, i256* _arg2, i256* _arg3, i256* _result)
{
dev::u256 arg1 = llvm2eth(*_arg1);
dev::u256 arg2 = llvm2eth(*_arg2);
dev::u256 arg3 = llvm2eth(*_arg3);
*_result = eth2llvm(dev::u256((dev::bigint(arg1) + dev::bigint(arg2)) % arg3));
}
}
}

4
libevmjit/BasicBlock.cpp

@ -109,7 +109,7 @@ void BasicBlock::LocalStack::synchronize(Stack& _evmStack)
}
// Push new values
for ( ; currIter < endIter; ++currIter)
for (; currIter < endIter; ++currIter)
{
assert(*currIter != nullptr);
_evmStack.push(*currIter);
@ -243,7 +243,7 @@ void BasicBlock::linkLocalStacks(std::vector<BasicBlock*> basicBlocks, llvm::IRB
{
if (getenv("EVMCC_DEBUG_BLOCKS"))
{
for (auto& pair: cfg)
for (auto& pair : cfg)
std::cerr << pair.second.bblock.llvm()->getName().str()
<< ": in " << pair.second.inputItems
<< ", out " << pair.second.outputItems

7
libevmjit/CMakeLists.txt

@ -20,6 +20,7 @@ target_link_libraries(${EXECUTABLE} ethcore)
target_link_libraries(${EXECUTABLE} evm)
target_link_libraries(${EXECUTABLE} evmface)
if ("${TARGET_PLATFORM}" STREQUAL "w64")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
target_link_libraries(${EXECUTABLE} gcc)
@ -30,14 +31,12 @@ if ("${TARGET_PLATFORM}" STREQUAL "w64")
target_link_libraries(${EXECUTABLE} iphlpapi)
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s)
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
elseif (UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
else ()
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
endif ()
# LLVM specific commands
# LLVM specific config
find_package(LLVM REQUIRED CONFIG)
@ -50,7 +49,7 @@ add_definitions(${LLVM_DEFINITIONS})
llvm_map_components_to_libnames(llvm_libs core support mcjit x86asmparser x86codegen)
target_link_libraries(evmjit ${llvm_libs})
# end of LLVM specific commands
# end of LLVM specific config

81
libevmjit/Compiler.cpp

@ -33,7 +33,9 @@ namespace jit
{
Compiler::Compiler():
m_builder(llvm::getGlobalContext())
m_builder(llvm::getGlobalContext()),
m_jumpTableBlock(),
m_badJumpBlock()
{
Type::init(m_builder.getContext());
}
@ -120,7 +122,7 @@ void Compiler::createBasicBlocks(bytesConstRef bytecode)
}
// Remove split points generated from jumps out of code or into data.
for (auto it = splitPoints.cbegin(); it != splitPoints.cend(); )
for (auto it = splitPoints.cbegin(); it != splitPoints.cend();)
{
if (*it > bytecode.size() || !validJumpTargets[*it])
it = splitPoints.erase(it);
@ -128,7 +130,7 @@ void Compiler::createBasicBlocks(bytesConstRef bytecode)
++it;
}
for (auto it = splitPoints.cbegin(); it != splitPoints.cend(); )
for (auto it = splitPoints.cbegin(); it != splitPoints.cend();)
{
auto beginInstIdx = *it;
++it;
@ -137,8 +139,8 @@ void Compiler::createBasicBlocks(bytesConstRef bytecode)
}
m_stopBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "Stop", m_mainFunc);
m_badJumpBlock = std::make_unique<BasicBlock>("BadJumpBlock", m_mainFunc, m_builder);
m_jumpTableBlock = std::make_unique<BasicBlock>("JumpTableBlock", m_mainFunc, m_builder);
m_badJumpBlock = std::unique_ptr<BasicBlock>(new BasicBlock("BadJumpBlock", m_mainFunc, m_builder));
m_jumpTableBlock = std::unique_ptr<BasicBlock>(new BasicBlock("JumpTableBlock", m_mainFunc, m_builder));
for (auto it = directJumpTargets.cbegin(); it != directJumpTargets.cend(); ++it)
{
@ -170,7 +172,7 @@ void Compiler::createBasicBlocks(bytesConstRef bytecode)
std::unique_ptr<llvm::Module> Compiler::compile(bytesConstRef bytecode)
{
auto module = std::make_unique<llvm::Module>("main", m_builder.getContext());
auto module = std::unique_ptr<llvm::Module>(new llvm::Module("main", m_builder.getContext()));
// Create main function
llvm::Type* mainFuncArgTypes[] = {m_builder.getInt32Ty(), Type::RuntimePtr}; // There must be int in first place because LLVM does not support other signatures
@ -372,14 +374,13 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode,
break;
}
/*case Instruction::NEG:
case Instruction::BNOT:
{
auto top = stack.pop();
auto zero = Constant::get(0);
auto res = m_builder.CreateSub(zero, top);
stack.push(res);
auto value = stack.pop();
auto ret = m_builder.CreateXor(value, llvm::APInt(256, -1, true), "bnot");
stack.push(ret);
break;
}*/
}
case Instruction::LT:
{
@ -505,6 +506,36 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode,
break;
}
case Instruction::SIGNEXTEND:
{
auto idx = stack.pop();
auto word = stack.pop();
auto k32_ = m_builder.CreateTrunc(idx, m_builder.getIntNTy(5), "k_32");
auto k32 = m_builder.CreateZExt(k32_, Type::i256);
auto k32x8 = m_builder.CreateMul(k32, Constant::get(8), "kx8");
// test for word >> (k * 8 + 7)
auto bitpos = m_builder.CreateAdd(k32x8, Constant::get(7), "bitpos");
auto bitval = m_builder.CreateLShr(word, bitpos, "bitval");
auto bittest = m_builder.CreateTrunc(bitval, m_builder.getInt1Ty(), "bittest");
auto mask_ = m_builder.CreateShl(Constant::get(1), bitpos);
auto mask = m_builder.CreateSub(mask_, Constant::get(1), "mask");
auto negmask = m_builder.CreateXor(mask, llvm::ConstantInt::getAllOnesValue(Type::i256), "negmask");
auto val1 = m_builder.CreateOr(word, negmask);
auto val0 = m_builder.CreateAnd(word, mask);
auto kInRange = m_builder.CreateICmpULE(idx, llvm::ConstantInt::get(Type::i256, 30));
auto result = m_builder.CreateSelect(kInRange,
m_builder.CreateSelect(bittest, val1, val0),
word);
stack.push(result);
break;
}
case Instruction::SHA3:
{
auto inOff = stack.pop();
@ -523,29 +554,28 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode,
case Instruction::ANY_PUSH:
{
auto numBytes = static_cast<size_t>(inst)-static_cast<size_t>(Instruction::PUSH1) + 1;
const auto numBytes = static_cast<size_t>(inst) - static_cast<size_t>(Instruction::PUSH1) + 1;
auto value = llvm::APInt(256, 0);
for (decltype(numBytes) i = 0; i < numBytes; ++i) // TODO: Use pc as iterator
for (auto lastPC = currentPC + numBytes; currentPC < lastPC;)
{
++currentPC;
value <<= 8;
value |= bytecode[currentPC];
value |= bytecode[++currentPC];
}
auto c = m_builder.getInt(value);
stack.push(c);
stack.push(m_builder.getInt(value));
break;
}
case Instruction::ANY_DUP:
{
auto index = static_cast<size_t>(inst)-static_cast<size_t>(Instruction::DUP1);
auto index = static_cast<size_t>(inst) - static_cast<size_t>(Instruction::DUP1);
stack.dup(index);
break;
}
case Instruction::ANY_SWAP:
{
auto index = static_cast<size_t>(inst)-static_cast<size_t>(Instruction::SWAP1) + 1;
auto index = static_cast<size_t>(inst) - static_cast<size_t>(Instruction::SWAP1) + 1;
stack.swap(index);
break;
}
@ -610,10 +640,8 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode,
{
auto pairIter = m_directJumpTargets.find(currentPC);
if (pairIter != m_directJumpTargets.end())
{
targetBlock = pairIter->second;
}
}
if (inst == Instruction::JUMP)
{
@ -625,10 +653,8 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode,
m_builder.CreateBr(targetBlock);
}
else
{
m_builder.CreateBr(m_jumpTableBlock->llvm());
}
}
else // JUMPI
{
stack.swap(1);
@ -636,8 +662,9 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode,
auto zero = Constant::get(0);
auto cond = m_builder.CreateICmpNE(val, zero, "nonzero");
// Assume the basic blocks are properly ordered:
assert(nextBasicBlock); // FIXME: JUMPI can be last instruction
if (!nextBasicBlock) // In case JUMPI is the last instruction
nextBasicBlock = m_stopBB;
if (targetBlock)
{
@ -645,10 +672,8 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode,
m_builder.CreateCondBr(cond, targetBlock, nextBasicBlock);
}
else
{
m_builder.CreateCondBr(cond, m_jumpTableBlock->llvm(), nextBasicBlock);
}
}
break;
}

7
libevmjit/ExecutionEngine.cpp

@ -1,9 +1,11 @@
#include "ExecutionEngine.h"
#include <csetjmp>
#include <chrono>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/ADT/Triple.h>
@ -16,6 +18,9 @@
#include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/Host.h>
#pragma GCC diagnostic pop
#include <libevm/VM.h>
#include "Runtime.h"

91
libevmjit/Ext.cpp

@ -6,6 +6,7 @@
#include <llvm/IR/IntrinsicInst.h>
#include <libdevcrypto/SHA3.h>
#include <libevm/FeeStructure.h>
#include "Runtime.h"
#include "Type.h"
@ -24,21 +25,14 @@ inline u256 fromAddress(Address _a)
return (u160)_a;
}
struct ExtData
{
const byte* calldata;
const byte* code;
};
Ext::Ext(RuntimeManager& _runtimeManager):
RuntimeHelper(_runtimeManager)
RuntimeHelper(_runtimeManager),
m_data()
{
auto&& ctx = m_builder.getContext();
auto module = getModule();
auto i256Ty = m_builder.getIntNTy(256);
auto i256PtrTy = i256Ty->getPointerTo();
auto i8PtrTy = m_builder.getInt8PtrTy();
m_args[0] = m_builder.CreateAlloca(i256Ty, nullptr, "ext.index");
m_args[1] = m_builder.CreateAlloca(i256Ty, nullptr, "ext.value");
@ -172,45 +166,50 @@ llvm::Value* Ext::codesizeAt(llvm::Value* _addr)
extern "C"
{
using namespace dev::eth::jit;
using namespace dev::eth::jit;
EXPORT void ext_store(Runtime* _rt, i256* _index, i256* _value)
{
EXPORT void ext_store(Runtime* _rt, i256* _index, i256* _value)
{
auto index = llvm2eth(*_index);
auto value = _rt->getExt().store(index); // Interface uses native endianness
*_value = eth2llvm(value);
}
}
EXPORT void ext_setStore(Runtime* _rt, i256* _index, i256* _value)
{
EXPORT void ext_setStore(Runtime* _rt, i256* _index, i256* _value)
{
auto index = llvm2eth(*_index);
auto value = llvm2eth(*_value);
_rt->getExt().setStore(index, value); // Interface uses native endianness
}
auto& ext = _rt->getExt();
EXPORT void ext_calldataload(Runtime* _rt, i256* _index, i256* _value)
{
if (value == 0 && ext.store(index) != 0) // If delete
ext.sub.refunds += c_sstoreRefundGas; // Increase refund counter
ext.setStore(index, value); // Interface uses native endianness
}
EXPORT void ext_calldataload(Runtime* _rt, i256* _index, i256* _value)
{
auto index = static_cast<size_t>(llvm2eth(*_index));
assert(index + 31 > index); // TODO: Handle large index
auto b = reinterpret_cast<byte*>(_value);
for (size_t i = index, j = 0; i <= index + 31; ++i, ++j)
b[j] = i < _rt->getExt().data.size() ? _rt->getExt().data[i] : 0; // Keep Big Endian
// TODO: It all can be done by adding padding to data or by using min() algorithm without branch
}
}
EXPORT void ext_balance(Runtime* _rt, h256* _address, i256* _value)
{
EXPORT void ext_balance(Runtime* _rt, h256* _address, i256* _value)
{
auto u = _rt->getExt().balance(right160(*_address));
*_value = eth2llvm(u);
}
}
EXPORT void ext_suicide(Runtime* _rt, h256* _address)
{
EXPORT void ext_suicide(Runtime* _rt, h256* _address)
{
_rt->getExt().suicide(right160(*_address));
}
}
EXPORT void ext_create(Runtime* _rt, i256* _endowment, i256* _initOff, i256* _initSize, h256* _address)
{
EXPORT void ext_create(Runtime* _rt, i256* _endowment, i256* _initOff, i256* _initSize, h256* _address)
{
auto&& ext = _rt->getExt();
auto endowment = llvm2eth(*_endowment);
@ -221,18 +220,18 @@ EXPORT void ext_create(Runtime* _rt, i256* _endowment, i256* _initOff, i256* _in
auto initOff = static_cast<size_t>(llvm2eth(*_initOff));
auto initSize = static_cast<size_t>(llvm2eth(*_initSize));
auto&& initRef = bytesConstRef(_rt->getMemory().data() + initOff, initSize);
OnOpFunc onOp{}; // TODO: Handle that thing
OnOpFunc onOp {}; // TODO: Handle that thing
h256 address(ext.create(endowment, &gas, initRef, onOp), h256::AlignRight);
*_address = address;
}
else
*_address = {};
}
}
EXPORT void ext_call(Runtime* _rt, i256* _gas, h256* _receiveAddress, i256* _value, i256* _inOff, i256* _inSize, i256* _outOff, i256* _outSize, h256* _codeAddress, i256* _ret)
{
EXPORT void ext_call(Runtime* _rt, i256* _gas, h256* _receiveAddress, i256* _value, i256* _inOff, i256* _inSize, i256* _outOff, i256* _outSize, h256* _codeAddress, i256* _ret)
{
auto&& ext = _rt->getExt();
auto value = llvm2eth(*_value);
@ -248,47 +247,47 @@ EXPORT void ext_call(Runtime* _rt, i256* _gas, h256* _receiveAddress, i256* _val
auto outSize = static_cast<size_t>(llvm2eth(*_outSize));
auto&& inRef = bytesConstRef(_rt->getMemory().data() + inOff, inSize);
auto&& outRef = bytesConstRef(_rt->getMemory().data() + outOff, outSize);
OnOpFunc onOp{}; // TODO: Handle that thing
OnOpFunc onOp {}; // TODO: Handle that thing
auto codeAddress = right160(*_codeAddress);
ret = ext.call(receiveAddress, value, inRef, &gas, outRef, onOp, {}, codeAddress);
}
*_gas = eth2llvm(gas);
_ret->a = ret ? 1 : 0;
}
}
EXPORT void ext_sha3(Runtime* _rt, i256* _inOff, i256* _inSize, i256* _ret)
{
EXPORT void ext_sha3(Runtime* _rt, i256* _inOff, i256* _inSize, i256* _ret)
{
auto inOff = static_cast<size_t>(llvm2eth(*_inOff));
auto inSize = static_cast<size_t>(llvm2eth(*_inSize));
auto dataRef = bytesConstRef(_rt->getMemory().data() + inOff, inSize);
auto hash = sha3(dataRef);
*_ret = *reinterpret_cast<i256*>(&hash);
}
}
EXPORT void ext_exp(Runtime* _rt, i256* _left, i256* _right, i256* _ret)
{
EXPORT void ext_exp(Runtime*, i256* _left, i256* _right, i256* _ret)
{
bigint left = llvm2eth(*_left);
bigint right = llvm2eth(*_right);
auto ret = static_cast<u256>(boost::multiprecision::powm(left, right, bigint(2) << 256));
*_ret = eth2llvm(ret);
}
}
EXPORT unsigned char* ext_codeAt(Runtime* _rt, h256* _addr256)
{
EXPORT unsigned char* ext_codeAt(Runtime* _rt, h256* _addr256)
{
auto&& ext = _rt->getExt();
auto addr = right160(*_addr256);
auto& code = ext.codeAt(addr);
return const_cast<unsigned char*>(code.data());
}
}
EXPORT void ext_codesizeAt(Runtime* _rt, h256* _addr256, i256* _ret)
{
EXPORT void ext_codesizeAt(Runtime* _rt, h256* _addr256, i256* _ret)
{
auto&& ext = _rt->getExt();
auto addr = right160(*_addr256);
auto& code = ext.codeAt(addr);
*_ret = eth2llvm(u256(code.size()));
}
}
}
}

18
libevmjit/GasMeter.cpp

@ -28,11 +28,9 @@ uint64_t getStepCost(Instruction inst) // TODO: Add this function to FeeSructure
{
case Instruction::STOP:
case Instruction::SUICIDE:
case Instruction::SSTORE: // Handle cost of SSTORE separately in GasMeter::countSStore()
return 0;
case Instruction::SSTORE:
return static_cast<uint64_t>(c_sstoreResetGas); // FIXME: Check store gas
case Instruction::SLOAD:
return static_cast<uint64_t>(c_sloadGas);
@ -118,7 +116,6 @@ void GasMeter::count(Instruction _inst)
m_checkCall = m_builder.CreateCall(m_gasCheckFunc, llvm::UndefValue::get(Type::i256));
}
if (_inst != Instruction::SSTORE) // Handle cost of SSTORE separately in countSStore()
m_blockCost += getStepCost(_inst);
if (isCostBlockEnd(_inst))
@ -129,20 +126,15 @@ void GasMeter::countSStore(Ext& _ext, llvm::Value* _index, llvm::Value* _newValu
{
assert(!m_checkCall); // Everything should've been commited before
static const auto sstoreCost = static_cast<uint64_t>(c_sstoreResetGas); // FIXME: Check store gas
// [ADD] if oldValue == 0 and newValue != 0 => 2*cost
// [DEL] if oldValue != 0 and newValue == 0 => 0
auto oldValue = _ext.store(_index);
auto oldValueIsZero = m_builder.CreateICmpEQ(oldValue, Constant::get(0), "oldValueIsZero");
auto newValueIsZero = m_builder.CreateICmpEQ(_newValue, Constant::get(0), "newValueIsZero");
auto oldValueIsntZero = m_builder.CreateICmpNE(oldValue, Constant::get(0), "oldValueIsntZero");
auto newValueIsntZero = m_builder.CreateICmpNE(_newValue, Constant::get(0), "newValueIsntZero");
auto isAdd = m_builder.CreateAnd(oldValueIsZero, newValueIsntZero, "isAdd");
auto isDel = m_builder.CreateAnd(oldValueIsntZero, newValueIsZero, "isDel");
auto cost = m_builder.CreateSelect(isAdd, Constant::get(2 * sstoreCost), Constant::get(sstoreCost), "cost");
cost = m_builder.CreateSelect(isDel, Constant::get(0), cost, "cost");
auto isInsert = m_builder.CreateAnd(oldValueIsZero, newValueIsntZero, "isInsert");
auto isDelete = m_builder.CreateAnd(oldValueIsntZero, newValueIsZero, "isDelete");
auto cost = m_builder.CreateSelect(isInsert, Constant::get(c_sstoreSetGas), Constant::get(c_sstoreResetGas), "cost");
cost = m_builder.CreateSelect(isDelete, Constant::get(0), cost, "cost");
createCall(m_gasCheckFunc, cost);
}

37
libevmjit/Memory.cpp

@ -74,7 +74,8 @@ llvm::Function* Memory::createRequireFunc(GasMeter& _gasMeter, RuntimeManager& _
m_builder.SetInsertPoint(resizeBB);
// Check gas first
auto wordsRequired = m_builder.CreateUDiv(m_builder.CreateAdd(sizeRequired, Constant::get(31)), Constant::get(32), "wordsRequired");
auto words = m_builder.CreateUDiv(m_builder.CreateAdd(size, Constant::get(31)), Constant::get(32), "words");
sizeRequired = m_builder.CreateMul(wordsRequired, Constant::get(32), "roundedSizeRequired");
auto words = m_builder.CreateUDiv(size, Constant::get(32), "words"); // size is always 32*k
auto newWords = m_builder.CreateSub(wordsRequired, words, "addtionalWords");
_gasMeter.checkMemory(newWords, m_builder);
// Resize
@ -89,7 +90,7 @@ llvm::Function* Memory::createRequireFunc(GasMeter& _gasMeter, RuntimeManager& _
return func;
}
llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType, GasMeter& _gasMeter)
llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType, GasMeter&)
{
auto isWord = _valueType == Type::i256;
@ -218,38 +219,14 @@ void Memory::dump(uint64_t _begin, uint64_t _end)
extern "C"
{
using namespace dev::eth::jit;
using namespace dev::eth::jit;
EXPORT uint8_t* mem_resize(Runtime* _rt, i256* _size)
{
EXPORT uint8_t* mem_resize(Runtime* _rt, i256* _size)
{
auto size = _size->a; // Trunc to 64-bit
auto& memory = _rt->getMemory();
memory.resize(size);
return memory.data();
}
EXPORT void evmccrt_memory_dump(uint64_t _begin, uint64_t _end)
{
//if (_end == 0)
// _end = Runtime::getMemory().size();
//std::cerr << "MEMORY: active size: " << std::dec
// << Runtime::getMemory().size() / 32 << " words\n";
//std::cerr << "MEMORY: dump from " << std::dec
// << _begin << " to " << _end << ":";
//if (_end <= _begin)
// return;
//_begin = _begin / 16 * 16;
//for (size_t i = _begin; i < _end; i++)
//{
// if ((i - _begin) % 16 == 0)
// std::cerr << '\n' << std::dec << i << ": ";
// auto b = Runtime::getMemory()[i];
// std::cerr << std::hex << std::setw(2) << static_cast<int>(b) << ' ';
//}
//std::cerr << std::endl;
}
}
} // extern "C"

3
libevmjit/Runtime.h

@ -1,9 +1,8 @@
#pragma once
#include <setjmp.h>
#include <vector>
#include <csetjmp>
#include <libevm/ExtVMFace.h>

34
libevmjit/Stack.cpp

@ -14,8 +14,8 @@ namespace eth
namespace jit
{
Stack::Stack(llvm::IRBuilder<>& _builder, RuntimeManager& _runtimeManager)
: CompilerHelper(_builder),
Stack::Stack(llvm::IRBuilder<>& _builder, RuntimeManager& _runtimeManager):
CompilerHelper(_builder),
m_runtimeManager(_runtimeManager)
{
m_arg = m_builder.CreateAlloca(Type::i256, nullptr, "stack.arg");
@ -36,9 +36,6 @@ Stack::Stack(llvm::IRBuilder<>& _builder, RuntimeManager& _runtimeManager)
m_set = Function::Create(FunctionType::get(Type::Void, getSetArgTypes, false), Linkage::ExternalLinkage, "stack_set", module);
}
Stack::~Stack()
{}
llvm::Value* Stack::get(size_t _index)
{
m_builder.CreateCall3(m_get, m_runtimeManager.getRuntimePtr(), llvm::ConstantInt::get(Type::Size, _index, false), m_arg);
@ -71,46 +68,45 @@ size_t Stack::maxStackSize = 0;
extern "C"
{
using namespace dev::eth::jit;
using namespace dev::eth::jit;
EXPORT void stack_pop(Runtime* _rt, uint64_t _count)
{
EXPORT void stack_pop(Runtime* _rt, uint64_t _count)
{
auto& stack = _rt->getStack();
if (stack.size() < _count)
longjmp(_rt->getJmpBuf(), static_cast<uint64_t>(ReturnCode::StackTooSmall));
stack.erase(stack.end() - _count, stack.end());
}
}
EXPORT void stack_push(Runtime* _rt, i256* _word)
{
EXPORT void stack_push(Runtime* _rt, i256* _word)
{
auto& stack = _rt->getStack();
stack.push_back(*_word);
if (stack.size() > Stack::maxStackSize)
Stack::maxStackSize = stack.size();
}
}
EXPORT void stack_get(Runtime* _rt, uint64_t _index, i256* _ret)
{
EXPORT void stack_get(Runtime* _rt, uint64_t _index, i256* _ret)
{
auto& stack = _rt->getStack();
// TODO: encode _index and stack size in the return code
if (stack.size() <= _index)
longjmp(_rt->getJmpBuf(), static_cast<uint64_t>(ReturnCode::StackTooSmall));
*_ret = *(stack.rbegin() + _index);
}
}
EXPORT void stack_set(Runtime* _rt, uint64_t _index, i256* _word)
{
EXPORT void stack_set(Runtime* _rt, uint64_t _index, i256* _word)
{
auto& stack = _rt->getStack();
// TODO: encode _index and stack size in the return code
if (stack.size() <= _index)
longjmp(_rt->getJmpBuf(), static_cast<uint64_t>(ReturnCode::StackTooSmall));
*(stack.rbegin() + _index) = *_word;
}
}
} // extern "C"

2
libevmjit/Stack.h

@ -15,9 +15,7 @@ class RuntimeManager;
class Stack : public CompilerHelper
{
public:
Stack(llvm::IRBuilder<>& builder, RuntimeManager& runtimeManager);
virtual ~Stack();
llvm::Value* get(size_t _index);
void set(size_t _index, llvm::Value* _value);

10
libevmjit/Type.cpp

@ -41,6 +41,16 @@ llvm::ConstantInt* Constant::get(uint64_t _n)
return llvm::ConstantInt::get(Type::i256, _n);
}
llvm::ConstantInt* Constant::get(u256 _n)
{
auto& backend = _n.backend();
auto words = reinterpret_cast<uint64_t*>(backend.limbs());
auto nWords = backend.limb_bits == 64 ? backend.size() : (backend.size() + 1) / 2;
llvm::APInt n(256, nWords, words);
assert(n.toString(10, false) == _n.str());
return static_cast<llvm::ConstantInt*>(llvm::ConstantInt::get(Type::i256, n));
}
llvm::ConstantInt* Constant::get(ReturnCode _returnCode)
{
return llvm::ConstantInt::get(Type::MainReturn, static_cast<uint64_t>(_returnCode));

2
libevmjit/Type.h

@ -3,6 +3,7 @@
#include <llvm/IR/Type.h>
#include <llvm/IR/Constants.h>
#include <libdevcore/Common.h>
namespace dev
{
@ -51,6 +52,7 @@ struct Constant
{
/// Returns word-size constant
static llvm::ConstantInt* get(uint64_t _n);
static llvm::ConstantInt* get(u256 _n);
static llvm::ConstantInt* get(ReturnCode _returnCode);
};

4
libevmjit/VM.cpp

@ -28,9 +28,11 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const&, uint64_t)
case ReturnCode::OutOfGas:
BOOST_THROW_EXCEPTION(OutOfGas());
case ReturnCode::StackTooSmall:
BOOST_THROW_EXCEPTION(StackTooSmall(1,0));
BOOST_THROW_EXCEPTION(StackTooSmall(1, 0));
case ReturnCode::BadInstruction:
BOOST_THROW_EXCEPTION(BadInstruction());
default:
break;
}
m_output = std::move(engine.returnData);

2
neth/CMakeLists.txt

@ -24,7 +24,7 @@ if(JSONRPC_LS)
target_link_libraries(${EXECUTABLE} ${JSONRPC_LS})
endif()
if(EVMCC)
if(EVMJIT)
target_link_libraries(${EXECUTABLE} evmjit)
endif()

9
test/CMakeLists.txt

@ -7,7 +7,6 @@ include_directories(..)
link_directories(../libethcore)
link_directories(../libethereum)
link_directories(../libevm)
link_directories(../libevmjit)
file(GLOB HEADERS "*.h")
add_executable(testeth ${SRC_LIST} ${HEADERS})
@ -20,13 +19,17 @@ target_link_libraries(testeth gmp)
target_link_libraries(testeth solidity)
target_link_libraries(testeth ${CRYPTOPP_LS})
target_link_libraries(testeth evm)
target_link_libraries(testeth evmjit)
if (EVMJIT)
target_link_libraries(testeth evmjit)
endif()
target_link_libraries(createRandomTest ethereum)
target_link_libraries(createRandomTest ethcore)
target_link_libraries(createRandomTest boost_chrono)
target_link_libraries(createRandomTest boost_unit_test_framework)
target_link_libraries(createRandomTest evmjit)
if (EVMJIT)
target_link_libraries(createRandomTest evmjit)
endif()
if ("${TARGET_PLATFORM}" STREQUAL "w64")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")

2
windows/LLVM.props

@ -14,7 +14,7 @@
<ClCompile>
<AdditionalIncludeDirectories>$(LLVMIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4800;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<PreprocessorDefinitions>ETH_JIT=$(LLVMEnabled);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>ETH_EVMJIT=$(LLVMEnabled);%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(LLVMLibDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

Loading…
Cancel
Save