Merge pull request #33 from ethereum/evm-instructions

EVM instructions table
This commit is contained in:
Paweł Bylica 2018-06-11 15:28:37 +02:00 committed by GitHub
commit 37cc64f5dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1897 additions and 11 deletions

View File

@ -9,9 +9,9 @@ if(TARGET evmc)
return()
endif()
option(EVMC_BUILD_TESTS "Build EVMC tests and test tools" OFF)
option(EVMC_BUILD_EXAMPLES "Build EVMC examples" OFF)
option(HUNTER_ENABLED "Enable Hunter package manager support" "${EVMC_BUILD_TESTS}")
option(EVMC_TESTING "Build EVMC tests and test tools" OFF)
option(EVMC_EXAMPLES "Build EVMC examples" OFF)
option(HUNTER_ENABLED "Enable Hunter package manager support" "${EVMC_TESTING}")
include(cmake/cable/bootstrap.cmake)
include(CableCompilerSettings)
@ -32,17 +32,22 @@ set(PROJECT_VERSION "0.1.0.dev0")
cable_configure_compiler(NO_STACK_PROTECTION)
set(include_dir ${PROJECT_SOURCE_DIR}/include)
add_library(evmc INTERFACE)
target_include_directories(evmc INTERFACE include)
add_library(evmc::evmc ALIAS evmc)
target_include_directories(evmc INTERFACE ${include_dir})
install(DIRECTORY include/evmc DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
if(EVMC_BUILD_TESTS)
add_subdirectory(lib)
if(EVMC_TESTING)
enable_testing()
add_subdirectory(test)
endif()
if(EVMC_BUILD_EXAMPLES)
if(EVMC_EXAMPLES)
add_subdirectory(examples)
endif()

View File

@ -9,10 +9,13 @@ jobs:
- run:
name: "Configure"
working_directory: ~/build
command: cmake ../project -DCMAKE_INSTALL_PREFIX=~/install -DBUILD_SHARED_LIBS=ON -DEVMC_BUILD_EXAMPLES=ON -DEVMC_BUILD_TESTS=ON
command: cmake ../project -DCMAKE_INSTALL_PREFIX=~/install -DBUILD_SHARED_LIBS=ON -DEVMC_EXAMPLES=ON -DEVMC_TESTING=ON
- run:
name: "Build"
command: cmake --build ~/build
- run:
name: "Unit tests"
command: ~/build/test/evmc-test
- run:
name: "Test"
command: cmake --build ~/build --target test

View File

@ -93,7 +93,7 @@ static struct evmc_result execute(struct evmc_instance* instance, struct evmc_co
struct evmc_uint256be value;
const struct evmc_uint256be index = {{0}};
context->fn_table->get_storage(&value, context, &msg->destination, &index);
value.bytes[31] += 1;
value.bytes[31]++;
context->fn_table->set_storage(context, &msg->destination, &index, &value);
ret.status_code = EVMC_SUCCESS;
return ret;

213
include/evmc/instructions.h Normal file
View File

@ -0,0 +1,213 @@
/* EVMC: Ethereum Client-VM Connector API.
* Copyright 2018 Pawel Bylica.
* Licensed under the MIT License. See the LICENSE file.
*/
#pragma once
#include <evmc/evmc.h>
#include <stdint.h>
#if __cplusplus
extern "C" {
#endif
/**
* The list of EVM 1 instructions from every EVM revision.
*/
enum evmc_instruction
{
STOP = 0x00,
ADD,
MUL,
SUB,
DIV,
SDIV,
MOD,
SMOD,
ADDMOD,
MULMOD,
EXP,
SIGNEXTEND,
LT = 0x10,
GT,
SLT,
SGT,
EQ,
ISZERO,
AND,
OR,
XOR,
NOT,
BYTE,
SHL,
SHR,
SAR,
SHA3 = 0x20,
ADDRESS = 0x30,
BALANCE,
ORIGIN,
CALLER,
CALLVALUE,
CALLDATALOAD,
CALLDATASIZE,
CALLDATACOPY,
CODESIZE,
CODECOPY,
GASPRICE,
EXTCODESIZE,
EXTCODECOPY,
RETURNDATASIZE = 0x3d,
RETURNDATACOPY = 0x3e,
BLOCKHASH = 0x40,
COINBASE,
TIMESTAMP,
NUMBER,
DIFFICULTY,
GASLIMIT,
POP = 0x50,
MLOAD,
MSTORE,
MSTORE8,
SLOAD,
SSTORE,
JUMP,
JUMPI,
PC,
MSIZE,
GAS,
JUMPDEST,
PUSH1 = 0x60,
PUSH2,
PUSH3,
PUSH4,
PUSH5,
PUSH6,
PUSH7,
PUSH8,
PUSH9,
PUSH10,
PUSH11,
PUSH12,
PUSH13,
PUSH14,
PUSH15,
PUSH16,
PUSH17,
PUSH18,
PUSH19,
PUSH20,
PUSH21,
PUSH22,
PUSH23,
PUSH24,
PUSH25,
PUSH26,
PUSH27,
PUSH28,
PUSH29,
PUSH30,
PUSH31,
PUSH32,
DUP1 = 0x80,
DUP2,
DUP3,
DUP4,
DUP5,
DUP6,
DUP7,
DUP8,
DUP9,
DUP10,
DUP11,
DUP12,
DUP13,
DUP14,
DUP15,
DUP16,
SWAP1 = 0x90,
SWAP2,
SWAP3,
SWAP4,
SWAP5,
SWAP6,
SWAP7,
SWAP8,
SWAP9,
SWAP10,
SWAP11,
SWAP12,
SWAP13,
SWAP14,
SWAP15,
SWAP16,
LOG0 = 0xa0,
LOG1,
LOG2,
LOG3,
LOG4,
CREATE = 0xf0,
CALL,
CALLCODE,
RETURN,
DELEGATECALL,
STATICCALL = 0xfa,
REVERT = 0xfd,
INVALID = 0xfe,
SELFDESTRUCT = 0xff,
};
/**
* Metrics for an EVM 1 instruction.
*
* Small integer types are used here to make the tables of metrics cache friendly.
*/
struct evmc_instruction_metrics
{
/** The instruction gas cost. Value -1 indicates undefined instruction. */
int16_t gas_cost;
/** The number of items the instruction pops from the EVM stack before execution. */
int8_t num_stack_arguments;
/** The number of items the instruction pushes to the EVM stack after execution. */
int8_t num_stack_returned_items;
};
/**
* Get the table of the EVM 1 instructions metrics.
*
* @param revision The EVM revision.
* @return The pointer to the array of 256 instruction metrics.
*/
const struct evmc_instruction_metrics* evmc_get_instruction_metrics_table(
enum evmc_revision revision);
/**
* Get the table of the EVM 1 instruction names.
*
* This table is EVM revision independent and contains the superset of the names of the instructions
* from all EVM revisions. Use evmc_get_instruction_metrics_table() to know if an instruction
* is present in the given EVM revision.
*
* The entries for undefined instructions contain null pointers.
*
* @return The pointer to the array of 256 instruction names.
*/
const char* const* evmc_get_instruction_name_table();
#if __cplusplus
}
#endif

5
lib/CMakeLists.txt Normal file
View File

@ -0,0 +1,5 @@
# EVMC: Ethereum Client-VM Connector API.
# Copyright 2018 Pawel Bylica.
# Licensed under the MIT License. See the LICENSE file.
add_subdirectory(instructions)

View File

@ -0,0 +1,9 @@
# EVMC: Ethereum Client-VM Connector API.
# Copyright 2018 Pawel Bylica.
# Licensed under the MIT License. See the LICENSE file.
add_library(instructions ${include_dir}/evmc/instructions.h instructions.c)
add_library(evmc::instructions ALIAS instructions)
target_include_directories(instructions PUBLIC ${include_dir})
install(TARGETS instructions EXPORT evmcTargets DESTINATION ${CMAKE_INSTALL_LIBDIR})

File diff suppressed because it is too large Load Diff

View File

@ -2,5 +2,9 @@
# Copyright 2018 Pawel Bylica.
# Licensed under the MIT License. See the LICENSE file.
hunter_add_package(GTest)
find_package(GTest CONFIG REQUIRED)
add_subdirectory(integration)
add_subdirectory(unittests)
add_subdirectory(vmtester)

View File

@ -0,0 +1,11 @@
# EVMC: Ethereum Client-VM Connector API.
# Copyright 2018 Pawel Bylica.
# Licensed under the MIT License. See the LICENSE file.
add_executable(
evmc-test
test_instructions.cpp
)
target_link_libraries(evmc-test PRIVATE instructions GTest::gtest GTest::main)
set_target_properties(evmc-test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ..)

View File

@ -0,0 +1,37 @@
// EVMC: Ethereum Client-VM Connector API.
// Copyright 2018 Pawel Bylica.
// Licensed under the MIT License. See the LICENSE file.
#include <evmc/instructions.h>
#include <gtest/gtest.h>
TEST(instructions, tangerine_whistle_hard_fork)
{
const auto h = evmc_get_instruction_metrics_table(EVMC_HOMESTEAD);
const auto tw = evmc_get_instruction_metrics_table(EVMC_TANGERINE_WHISTLE);
EXPECT_EQ(h[EXTCODESIZE].gas_cost, 20);
EXPECT_EQ(tw[EXTCODESIZE].gas_cost, 700);
EXPECT_EQ(h[EXTCODECOPY].gas_cost, 20);
EXPECT_EQ(tw[EXTCODECOPY].gas_cost, 700);
EXPECT_EQ(h[BALANCE].gas_cost, 20);
EXPECT_EQ(tw[BALANCE].gas_cost, 400);
EXPECT_EQ(h[SLOAD].gas_cost, 50);
EXPECT_EQ(tw[SLOAD].gas_cost, 200);
EXPECT_EQ(h[CALL].gas_cost, 40);
EXPECT_EQ(tw[CALL].gas_cost, 700);
EXPECT_EQ(h[CALLCODE].gas_cost, 40);
EXPECT_EQ(tw[CALLCODE].gas_cost, 700);
EXPECT_EQ(h[DELEGATECALL].gas_cost, 40);
EXPECT_EQ(tw[DELEGATECALL].gas_cost, 700);
EXPECT_EQ(h[SELFDESTRUCT].gas_cost, 0);
EXPECT_EQ(tw[SELFDESTRUCT].gas_cost, 5000);
}

View File

@ -7,9 +7,6 @@ include(GNUInstallDirs)
hunter_add_package(Boost COMPONENTS program_options filesystem system)
find_package(Boost CONFIG REQUIRED program_options filesystem system)
hunter_add_package(GTest)
find_package(GTest CONFIG REQUIRED)
add_executable(evmc-vmtester vmtester.hpp vmtester.cpp tests.cpp)
target_link_libraries(