Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build intx bignum library in CMake #245

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ endif()
project(hera)

include(ProjectBinaryen)
include(ProjectIntX)

add_subdirectory(evmc)
add_subdirectory(evm2wasm)
Expand Down
54 changes: 54 additions & 0 deletions cmake/ProjectIntX.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
if(ProjectIntXIncluded)
return()
endif()

set(ProjectIntXIncluded TRUE)

include(ExternalProject)
include(GNUInstallDirs)

set(prefix ${CMAKE_BINARY_DIR}/deps)
set(source_dir ${prefix}/src/intx)
set(binary_dir ${prefix}/src/intx-build)

set(intx_include_dir ${source_dir}/include/intx)
set(intx_lib ${binary_dir}/libs/intx/libintx.a)

set(patch_command sed -i -e "$ d" ${source_dir}/CMakeLists.txt)
set(build_command cmake --build <BINARY_DIR>)
set(install_command cmake --build <BINARY_DIR> --target install)

if(CMAKE_GENERATOR STREQUAL Ninja)
if($ENV{BUILD_PARALLEL_JOBS})
set(build_command cmake --build <BINARY_DIR> -- -j $ENV{BUILD_PARALLEL_JOBS})
message(STATUS "Ninja $ENV{BUILD_PARALLEL_JOBS}")
endif()
endif()

ExternalProject_Add(intx
PREFIX ${prefix}
GIT_REPOSITORY https://github.com/chfast/intx.git
GIT_TAG 1a10f4fc3433d5ce88ea4c6067002680e2ea0385
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
SOURCE_DIR ${source_dir}
BINARY_DIR ${binary_dir}
PATCH_COMMAND ${patch_command}
BUILD_COMMAND ${build_command}
INSTALL_COMMAND ${install_command}
INSTALL_DIR ${prefix}/${CMAKE_INSTALL_LIBDIR}
BUILD_BYPRODUCTS ${intx_lib}
)

add_library(intx::intx STATIC IMPORTED)

file(MAKE_DIRECTORY ${intx_include_dir})
set_target_properties(
intx::intx
PROPERTIES
IMPORTED_LOCATION_RELEASE ${intx_lib}
INTERFACE_INCLUDE_DIRECTORIES ${intx_include_dir}
INTERFACE_LINK_LIBRARIES ${intx_lib}
)

add_dependencies(intx::intx intx)
3 changes: 2 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ if(HERA_DEBUGGING)
endif()

target_include_directories(hera PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${evm_include_dir})
target_link_libraries(hera PRIVATE evmc libevm2wasm binaryen::binaryen Threads::Threads)
target_link_libraries(hera PRIVATE evmc libevm2wasm binaryen::binaryen
Threads::Threads intx::intx)
if(NOT WIN32)
if(CMAKE_COMPILER_IS_GNUCXX)
set_target_properties(hera PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
Expand Down
7 changes: 5 additions & 2 deletions src/eei.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@

#include <stdexcept>
#include <array>

#include <intx.hpp>

#include "eei.h"
#include "exceptions.h"
#include "evm-instructions.h"
Expand Down Expand Up @@ -974,11 +977,11 @@ inline int64_t maxCallGas(int64_t gas) {
ensureCondition(safeLoadUint128(balance) >= safeLoadUint128(value), OutOfGasException, "Out of gas.");
}

uint64_t EthereumInterface::safeLoadUint128(evmc_uint256be const& value)
intx::uint128 EthereumInterface::safeLoadUint128(evmc_uint256be const& value)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know that GCC / clang have unsigned __int128?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chfast would have been cool if you could have mentioned that when the original issue was created :)

But according to https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html :

As an extension the integer scalar type __int128 is supported for targets which have an integer mode wide enough to hold 128 bits.
There is no support in GCC for expressing an integer constant of type __int128 for targets with long long integer less than 128 bits wide.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we can assume it works for x86-64 but not much else until we investigate

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't aware that 128-bit is the max precision you need.

Anyway, the type is available on 64-bit targets. Because you don't support MSVC at the moment it can be used as a temporary solution.

{
// TODO: use a specific error code here?
ensureCondition(!exceedsUint128(value), OutOfGasException, "Value exceeds 128 bits.");
uint64_t ret = 0;
intx::uint128 ret = 0;
for (unsigned i = 16; i < 32; i++) {
ret <<= 8;
ret |= value.bytes[i];
Expand Down
5 changes: 4 additions & 1 deletion src/eei.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
#include <wasm.h>
#include <wasm-binary.h>
#include <evmc/evmc.h>

#include <intx.hpp>

#include "shell-interface.h"
#include "hera.h"
#include "exceptions.h"
Expand Down Expand Up @@ -87,7 +90,7 @@ struct EthereumInterface : ShellExternalInterface {

void ensureSenderBalance(evmc_uint256be const& value);

static uint64_t safeLoadUint128(evmc_uint256be const& value);
static intx::uint128 safeLoadUint128(evmc_uint256be const& value);

/* Checks if host supplied 256 bit value exceeds UINT64_MAX */
static bool exceedsUint64(evmc_uint256be const& value);
Expand Down