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

Merge evmone into assigner library #20

Merged
merged 7 commits into from
Jun 18, 2024
Merged
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
29 changes: 0 additions & 29 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -110,41 +110,12 @@ endif()

include(CTest)

set(include_dir ${CMAKE_CURRENT_SOURCE_DIR}/include)

add_subdirectory(lib)

# INSTALL

set(install_targets evmone)
if(TARGET evmone-standalone)
list(APPEND install_targets evmone-standalone)
endif()
if(TARGET evm-test)
list(APPEND install_targets evm-test)
endif()
if(TARGET evmone-bench)
list(APPEND install_targets evmone-bench)
endif()

set_target_properties(
${install_targets} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}
)

install(TARGETS ${install_targets} EXPORT evmoneTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

install(DIRECTORY ${include_dir}/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

set(CONFIG_PATH ${CMAKE_INSTALL_LIBDIR}/cmake/evm-assigner)
set(TARGET_NAMESPACE evm-assigner::)
install(EXPORT evmoneTargets NAMESPACE ${TARGET_NAMESPACE} DESTINATION ${CONFIG_PATH})
akokoshn marked this conversation as resolved.
Show resolved Hide resolved
install(EXPORT assignerTargets NAMESPACE ${TARGET_NAMESPACE} DESTINATION ${CONFIG_PATH})

include(CMakePackageConfigHelpers)
Expand Down
1 change: 0 additions & 1 deletion cmake/Config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@ find_dependency(evmc REQUIRED)
find_dependency(intx REQUIRED)
find_dependency(ethash REQUIRED)

include("${CMAKE_CURRENT_LIST_DIR}/evmoneTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/assignerTargets.cmake")
21 changes: 0 additions & 21 deletions include/evmone/evmone.h

This file was deleted.

1 change: 0 additions & 1 deletion lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@

find_package(intx CONFIG REQUIRED)

add_subdirectory(evmone)
add_subdirectory(assigner)
33 changes: 22 additions & 11 deletions lib/assigner/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,33 @@ cmake_policy(SET CMP0063 NEW)

option(BUILD_ASSIGNER_TESTS "Build unit tests" FALSE)

add_library(${PROJECT_NAME} STATIC src/vm_host.cpp src/handler_base.cpp)
set(evmone_sources
${CMAKE_CURRENT_SOURCE_DIR}/evmone/baseline.cpp
${CMAKE_CURRENT_SOURCE_DIR}/evmone/baseline_instruction_table.cpp
${CMAKE_CURRENT_SOURCE_DIR}/evmone/eof.cpp
)

add_library(${PROJECT_NAME} STATIC ${evmone_sources})

target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_20)

find_package(crypto3 REQUIRED)
find_package(blueprint_crypto3 REQUIRED)

target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../evmone>)
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/evmone>)

target_link_libraries(${PROJECT_NAME}
PUBLIC evmone crypto3::all blueprint
PRIVATE ethash::keccak)
PUBLIC evmc::evmc intx::intx crypto3::all blueprint ethash::keccak)

set_target_properties(
${PROJECT_NAME}
PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_SOVERSION}
)

# Install assigner headers
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
Expand All @@ -26,14 +40,11 @@ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
install(TARGETS ${PROJECT_NAME} EXPORT assignerTargets DESTINATION ${CMAKE_INSTALL_LIBDIR})

# Install evmone headers
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../evmone/vm.hpp
${CMAKE_CURRENT_SOURCE_DIR}/../evmone/execution_state.hpp
${CMAKE_CURRENT_SOURCE_DIR}/../evmone/tracing.hpp
${CMAKE_CURRENT_SOURCE_DIR}/../evmone/baseline.hpp
${CMAKE_CURRENT_SOURCE_DIR}/../evmone/eof.hpp
${CMAKE_CURRENT_SOURCE_DIR}/../evmone/instructions_opcodes.hpp
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/evmone/execution_state.hpp
${CMAKE_CURRENT_SOURCE_DIR}/evmone/baseline.hpp
${CMAKE_CURRENT_SOURCE_DIR}/evmone/eof.hpp
${CMAKE_CURRENT_SOURCE_DIR}/evmone/instructions_opcodes.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

if(BUILD_ASSIGNER_TESTS)
add_subdirectory(test)
endif()
86 changes: 86 additions & 0 deletions lib/assigner/evmone/baseline.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// evmone: Fast Ethereum Virtual Machine implementation
// Copyright 2020 The evmone Authors.
// SPDX-License-Identifier: Apache-2.0

#include "baseline.hpp"

#ifdef NDEBUG
#define release_inline gnu::always_inline, msvc::forceinline
#else
#define release_inline
#endif

#if defined(__GNUC__)
#define ASM_COMMENT(COMMENT) asm("# " #COMMENT) // NOLINT(hicpp-no-assembler)
#else
#define ASM_COMMENT(COMMENT)
#endif

namespace evmone::baseline
{
namespace
{
CodeAnalysis::JumpdestMap analyze_jumpdests(bytes_view code)
{
// To find if op is any PUSH opcode (OP_PUSH1 <= op <= OP_PUSH32)
// it can be noticed that OP_PUSH32 is INT8_MAX (0x7f) therefore
// static_cast<int8_t>(op) <= OP_PUSH32 is always true and can be skipped.
static_assert(OP_PUSH32 == std::numeric_limits<int8_t>::max());

CodeAnalysis::JumpdestMap map(code.size()); // Allocate and init bitmap with zeros.
for (size_t i = 0; i < code.size(); ++i)
{
const auto op = code[i];
if (static_cast<int8_t>(op) >= OP_PUSH1) // If any PUSH opcode (see explanation above).
i += op - size_t{OP_PUSH1 - 1}; // Skip PUSH data.
else if (op == OP_JUMPDEST)
map[i] = true;
}

return map;
}

std::unique_ptr<uint8_t[]> pad_code(bytes_view code)
{
// We need at most 33 bytes of code padding: 32 for possible missing all data bytes of PUSH32
// at the very end of the code; and one more byte for STOP to guarantee there is a terminating
// instruction at the code end.
constexpr auto padding = 32 + 1;

// Using "raw" new operator instead of std::make_unique() to get uninitialized array.
std::unique_ptr<uint8_t[]> padded_code{new uint8_t[code.size() + padding]};
std::copy(std::begin(code), std::end(code), padded_code.get());
std::fill_n(&padded_code[code.size()], padding, uint8_t{OP_STOP});
return padded_code;
}


CodeAnalysis analyze_legacy(bytes_view code)
{
// TODO: The padded code buffer and jumpdest bitmap can be created with single allocation.
return {pad_code(code), code.size(), analyze_jumpdests(code)};
}

CodeAnalysis analyze_eof1(bytes_view container)
{
auto header = read_valid_eof1_header(container);

// Extract all code sections as single buffer reference.
// TODO: It would be much easier if header had code_sections_offset and data_section_offset
// with code_offsets[] being relative to code_sections_offset.
const auto code_sections_offset = header.code_offsets[0];
const auto code_sections_end = size_t{header.code_offsets.back()} + header.code_sizes.back();
const auto executable_code =
container.substr(code_sections_offset, code_sections_end - code_sections_offset);

return CodeAnalysis{executable_code, std::move(header)};
}
} // namespace

CodeAnalysis analyze(evmc_revision rev, bytes_view code)
{
if (rev < EVMC_PRAGUE || !is_eof_container(code))
return analyze_legacy(code);
return analyze_eof1(code);
}
} // namespace evmone::baseline
Loading
Loading