diff --git a/CMakeLists.txt b/CMakeLists.txt index 954768ef3..76b280b29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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() diff --git a/circle.yml b/circle.yml index 27fad9d85..c548aa542 100644 --- a/circle.yml +++ b/circle.yml @@ -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 diff --git a/examples/examplevm/examplevm.c b/examples/examplevm/examplevm.c index f60da76ff..0ff1ab87a 100644 --- a/examples/examplevm/examplevm.c +++ b/examples/examplevm/examplevm.c @@ -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; diff --git a/include/evmc/instructions.h b/include/evmc/instructions.h new file mode 100644 index 000000000..71756d40c --- /dev/null +++ b/include/evmc/instructions.h @@ -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 + +#include + +#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 diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt new file mode 100644 index 000000000..af298255c --- /dev/null +++ b/lib/CMakeLists.txt @@ -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) diff --git a/lib/instructions/CMakeLists.txt b/lib/instructions/CMakeLists.txt new file mode 100644 index 000000000..fafed2c99 --- /dev/null +++ b/lib/instructions/CMakeLists.txt @@ -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}) diff --git a/lib/instructions/instructions.c b/lib/instructions/instructions.c new file mode 100644 index 000000000..1ea217788 --- /dev/null +++ b/lib/instructions/instructions.c @@ -0,0 +1,1602 @@ +/* EVMC: Ethereum Client-VM Connector API. + * Copyright 2018 Pawel Bylica. + * Licensed under the MIT License. See the LICENSE file. + */ + +#include + +/** Marks an instruction as undefined. */ +#define UNDEFINED -1 + +/** + * Gas price tiers, names from Yellow Paper. + * @{ + */ +#define ZERO 0 +#define BASE 2 +#define VERYLOW 3 +#define LOW 5 +#define MID 8 +#define HIGH 10 + +/** @} */ + +static struct evmc_instruction_metrics constantinople_metrics[256] = { + /* STOP = 0x00 */ {ZERO, 0, 0}, + /* ADD = 0x01 */ {VERYLOW, 2, 1}, + /* MUL = 0x02 */ {LOW, 2, 1}, + /* SUB = 0x03 */ {VERYLOW, 2, 1}, + /* DIV = 0x04 */ {LOW, 2, 1}, + /* SDIV = 0x05 */ {LOW, 2, 1}, + /* MOD = 0x06 */ {LOW, 2, 1}, + /* SMOD = 0x07 */ {LOW, 2, 1}, + /* ADDMOD = 0x08 */ {MID, 3, 1}, + /* MULMOD = 0x09 */ {MID, 3, 1}, + /* EXP = 0x0a */ {10, 2, 1}, + /* SIGNEXTEND = 0x0b */ {LOW, 2, 1}, + /* = 0x0c */ {UNDEFINED, 0, 0}, + /* = 0x0d */ {UNDEFINED, 0, 0}, + /* = 0x0e */ {UNDEFINED, 0, 0}, + /* = 0x0f */ {UNDEFINED, 0, 0}, + /* LT = 0x10 */ {VERYLOW, 2, 1}, + /* GT = 0x11 */ {VERYLOW, 2, 1}, + /* SLT = 0x12 */ {VERYLOW, 2, 1}, + /* SGT = 0x13 */ {VERYLOW, 2, 1}, + /* EQ = 0x14 */ {VERYLOW, 2, 1}, + /* ISZERO = 0x15 */ {VERYLOW, 1, 1}, + /* AND = 0x16 */ {VERYLOW, 2, 1}, + /* OR = 0x17 */ {VERYLOW, 2, 1}, + /* XOR = 0x18 */ {VERYLOW, 2, 1}, + /* NOT = 0x19 */ {VERYLOW, 1, 1}, + /* BYTE = 0x1a */ {VERYLOW, 2, 1}, + /* SHL = 0x1b */ {VERYLOW, 2, 1}, + /* SHR = 0x1c */ {VERYLOW, 2, 1}, + /* SAR = 0x1d */ {VERYLOW, 2, 1}, + /* = 0x1e */ {UNDEFINED, 0, 0}, + /* = 0x1f */ {UNDEFINED, 0, 0}, + /* SHA3 = 0x20 */ {30, 2, 1}, + /* = 0x21 */ {UNDEFINED, 0, 0}, + /* = 0x22 */ {UNDEFINED, 0, 0}, + /* = 0x23 */ {UNDEFINED, 0, 0}, + /* = 0x24 */ {UNDEFINED, 0, 0}, + /* = 0x25 */ {UNDEFINED, 0, 0}, + /* = 0x26 */ {UNDEFINED, 0, 0}, + /* = 0x27 */ {UNDEFINED, 0, 0}, + /* = 0x28 */ {UNDEFINED, 0, 0}, + /* = 0x29 */ {UNDEFINED, 0, 0}, + /* = 0x2a */ {UNDEFINED, 0, 0}, + /* = 0x2b */ {UNDEFINED, 0, 0}, + /* = 0x2c */ {UNDEFINED, 0, 0}, + /* = 0x2d */ {UNDEFINED, 0, 0}, + /* = 0x2e */ {UNDEFINED, 0, 0}, + /* = 0x2f */ {UNDEFINED, 0, 0}, + /* ADDRESS = 0x30 */ {BASE, 0, 1}, + /* BALANCE = 0x31 */ {400, 1, 1}, + /* ORIGIN = 0x32 */ {BASE, 0, 1}, + /* CALLER = 0x33 */ {BASE, 0, 1}, + /* CALLVALUE = 0x34 */ {BASE, 0, 1}, + /* CALLDATALOAD = 0x35 */ {VERYLOW, 1, 1}, + /* CALLDATASIZE = 0x36 */ {BASE, 0, 1}, + /* CALLDATACOPY = 0x37 */ {VERYLOW, 3, 0}, + /* CODESIZE = 0x38 */ {BASE, 0, 1}, + /* CODECOPY = 0x39 */ {VERYLOW, 3, 0}, + /* GASPRICE = 0x3a */ {BASE, 0, 1}, + /* EXTCODESIZE = 0x3b */ {700, 1, 1}, + /* EXTCODECOPY = 0x3c */ {700, 4, 0}, + /* RETURNDATASIZE = 0x3d */ {BASE, 0, 1}, + /* RETURNDATACOPY = 0x3e */ {VERYLOW, 3, 0}, + /* = 0x3f */ {UNDEFINED, 0, 0}, + /* BLOCKHASH = 0x40 */ {20, 1, 1}, + /* COINBASE = 0x41 */ {BASE, 0, 1}, + /* TIMESTAMP = 0x42 */ {BASE, 0, 1}, + /* NUMBER = 0x43 */ {BASE, 0, 1}, + /* DIFFICULTY = 0x44 */ {BASE, 0, 1}, + /* GASLIMIT = 0x45 */ {BASE, 0, 1}, + /* = 0x46 */ {UNDEFINED, 0, 0}, + /* = 0x47 */ {UNDEFINED, 0, 0}, + /* = 0x48 */ {UNDEFINED, 0, 0}, + /* = 0x49 */ {UNDEFINED, 0, 0}, + /* = 0x4a */ {UNDEFINED, 0, 0}, + /* = 0x4b */ {UNDEFINED, 0, 0}, + /* = 0x4c */ {UNDEFINED, 0, 0}, + /* = 0x4d */ {UNDEFINED, 0, 0}, + /* = 0x4e */ {UNDEFINED, 0, 0}, + /* = 0x4f */ {UNDEFINED, 0, 0}, + /* POP = 0x50 */ {BASE, 1, 0}, + /* MLOAD = 0x51 */ {VERYLOW, 1, 1}, + /* MSTORE = 0x52 */ {VERYLOW, 2, 0}, + /* MSTORE8 = 0x53 */ {VERYLOW, 2, 0}, + /* SLOAD = 0x54 */ {200, 1, 1}, + /* SSTORE = 0x55 */ {0, 2, 0}, + /* JUMP = 0x56 */ {MID, 1, 0}, + /* JUMPI = 0x57 */ {HIGH, 2, 0}, + /* PC = 0x58 */ {BASE, 0, 1}, + /* MSIZE = 0x59 */ {BASE, 0, 1}, + /* GAS = 0x5a */ {BASE, 0, 1}, + /* JUMPDEST = 0x5b */ {1, 0, 0}, + /* = 0x5c */ {UNDEFINED, 0, 0}, + /* = 0x5d */ {UNDEFINED, 0, 0}, + /* = 0x5e */ {UNDEFINED, 0, 0}, + /* = 0x5f */ {UNDEFINED, 0, 0}, + /* PUSH1 = 0x60 */ {VERYLOW, 0, 1}, + /* PUSH2 = 0x61 */ {VERYLOW, 0, 1}, + /* PUSH3 = 0x62 */ {VERYLOW, 0, 1}, + /* PUSH4 = 0x63 */ {VERYLOW, 0, 1}, + /* PUSH5 = 0x64 */ {VERYLOW, 0, 1}, + /* PUSH6 = 0x65 */ {VERYLOW, 0, 1}, + /* PUSH7 = 0x66 */ {VERYLOW, 0, 1}, + /* PUSH8 = 0x67 */ {VERYLOW, 0, 1}, + /* PUSH9 = 0x68 */ {VERYLOW, 0, 1}, + /* PUSH10 = 0x69 */ {VERYLOW, 0, 1}, + /* PUSH11 = 0x6a */ {VERYLOW, 0, 1}, + /* PUSH12 = 0x6b */ {VERYLOW, 0, 1}, + /* PUSH13 = 0x6c */ {VERYLOW, 0, 1}, + /* PUSH14 = 0x6d */ {VERYLOW, 0, 1}, + /* PUSH15 = 0x6e */ {VERYLOW, 0, 1}, + /* PUSH16 = 0x6f */ {VERYLOW, 0, 1}, + /* PUSH17 = 0x70 */ {VERYLOW, 0, 1}, + /* PUSH18 = 0x71 */ {VERYLOW, 0, 1}, + /* PUSH19 = 0x72 */ {VERYLOW, 0, 1}, + /* PUSH20 = 0x73 */ {VERYLOW, 0, 1}, + /* PUSH21 = 0x74 */ {VERYLOW, 0, 1}, + /* PUSH22 = 0x75 */ {VERYLOW, 0, 1}, + /* PUSH23 = 0x76 */ {VERYLOW, 0, 1}, + /* PUSH24 = 0x77 */ {VERYLOW, 0, 1}, + /* PUSH25 = 0x78 */ {VERYLOW, 0, 1}, + /* PUSH26 = 0x79 */ {VERYLOW, 0, 1}, + /* PUSH27 = 0x7a */ {VERYLOW, 0, 1}, + /* PUSH28 = 0x7b */ {VERYLOW, 0, 1}, + /* PUSH29 = 0x7c */ {VERYLOW, 0, 1}, + /* PUSH30 = 0x7d */ {VERYLOW, 0, 1}, + /* PUSH31 = 0x7e */ {VERYLOW, 0, 1}, + /* PUSH32 = 0x7f */ {VERYLOW, 0, 1}, + /* DUP1 = 0x80 */ {VERYLOW, 1, 2}, + /* DUP2 = 0x81 */ {VERYLOW, 2, 3}, + /* DUP3 = 0x82 */ {VERYLOW, 3, 4}, + /* DUP4 = 0x83 */ {VERYLOW, 4, 5}, + /* DUP5 = 0x84 */ {VERYLOW, 5, 6}, + /* DUP6 = 0x85 */ {VERYLOW, 6, 7}, + /* DUP7 = 0x86 */ {VERYLOW, 7, 8}, + /* DUP8 = 0x87 */ {VERYLOW, 8, 9}, + /* DUP9 = 0x88 */ {VERYLOW, 9, 10}, + /* DUP10 = 0x89 */ {VERYLOW, 10, 11}, + /* DUP11 = 0x8a */ {VERYLOW, 11, 12}, + /* DUP12 = 0x8b */ {VERYLOW, 12, 13}, + /* DUP13 = 0x8c */ {VERYLOW, 13, 14}, + /* DUP14 = 0x8d */ {VERYLOW, 14, 15}, + /* DUP15 = 0x8e */ {VERYLOW, 15, 16}, + /* DUP16 = 0x8f */ {VERYLOW, 16, 17}, + /* SWAP1 = 0x90 */ {VERYLOW, 2, 2}, + /* SWAP2 = 0x91 */ {VERYLOW, 3, 3}, + /* SWAP3 = 0x92 */ {VERYLOW, 4, 4}, + /* SWAP4 = 0x93 */ {VERYLOW, 5, 5}, + /* SWAP5 = 0x94 */ {VERYLOW, 6, 6}, + /* SWAP6 = 0x95 */ {VERYLOW, 7, 7}, + /* SWAP7 = 0x96 */ {VERYLOW, 8, 8}, + /* SWAP8 = 0x97 */ {VERYLOW, 9, 9}, + /* SWAP9 = 0x98 */ {VERYLOW, 10, 10}, + /* SWAP10 = 0x99 */ {VERYLOW, 11, 11}, + /* SWAP11 = 0x9a */ {VERYLOW, 12, 12}, + /* SWAP12 = 0x9b */ {VERYLOW, 13, 13}, + /* SWAP13 = 0x9c */ {VERYLOW, 14, 14}, + /* SWAP14 = 0x9d */ {VERYLOW, 15, 15}, + /* SWAP15 = 0x9e */ {VERYLOW, 16, 16}, + /* SWAP16 = 0x9f */ {VERYLOW, 17, 17}, + /* LOG0 = 0xa0 */ {1 * 375, 2, 0}, + /* LOG1 = 0xa1 */ {2 * 375, 3, 0}, + /* LOG2 = 0xa2 */ {3 * 375, 4, 0}, + /* LOG3 = 0xa3 */ {4 * 375, 5, 0}, + /* LOG4 = 0xa4 */ {5 * 375, 6, 0}, + /* = 0xa5 */ {UNDEFINED, 0, 0}, + /* = 0xa6 */ {UNDEFINED, 0, 0}, + /* = 0xa7 */ {UNDEFINED, 0, 0}, + /* = 0xa8 */ {UNDEFINED, 0, 0}, + /* = 0xa9 */ {UNDEFINED, 0, 0}, + /* = 0xaa */ {UNDEFINED, 0, 0}, + /* = 0xab */ {UNDEFINED, 0, 0}, + /* = 0xac */ {UNDEFINED, 0, 0}, + /* = 0xad */ {UNDEFINED, 0, 0}, + /* = 0xae */ {UNDEFINED, 0, 0}, + /* = 0xaf */ {UNDEFINED, 0, 0}, + /* = 0xb0 */ {UNDEFINED, 0, 0}, + /* = 0xb1 */ {UNDEFINED, 0, 0}, + /* = 0xb2 */ {UNDEFINED, 0, 0}, + /* = 0xb3 */ {UNDEFINED, 0, 0}, + /* = 0xb4 */ {UNDEFINED, 0, 0}, + /* = 0xb5 */ {UNDEFINED, 0, 0}, + /* = 0xb6 */ {UNDEFINED, 0, 0}, + /* = 0xb7 */ {UNDEFINED, 0, 0}, + /* = 0xb8 */ {UNDEFINED, 0, 0}, + /* = 0xb9 */ {UNDEFINED, 0, 0}, + /* = 0xba */ {UNDEFINED, 0, 0}, + /* = 0xbb */ {UNDEFINED, 0, 0}, + /* = 0xbc */ {UNDEFINED, 0, 0}, + /* = 0xbd */ {UNDEFINED, 0, 0}, + /* = 0xbe */ {UNDEFINED, 0, 0}, + /* = 0xbf */ {UNDEFINED, 0, 0}, + /* = 0xc0 */ {UNDEFINED, 0, 0}, + /* = 0xc1 */ {UNDEFINED, 0, 0}, + /* = 0xc2 */ {UNDEFINED, 0, 0}, + /* = 0xc3 */ {UNDEFINED, 0, 0}, + /* = 0xc4 */ {UNDEFINED, 0, 0}, + /* = 0xc5 */ {UNDEFINED, 0, 0}, + /* = 0xc6 */ {UNDEFINED, 0, 0}, + /* = 0xc7 */ {UNDEFINED, 0, 0}, + /* = 0xc8 */ {UNDEFINED, 0, 0}, + /* = 0xc9 */ {UNDEFINED, 0, 0}, + /* = 0xca */ {UNDEFINED, 0, 0}, + /* = 0xcb */ {UNDEFINED, 0, 0}, + /* = 0xcc */ {UNDEFINED, 0, 0}, + /* = 0xcd */ {UNDEFINED, 0, 0}, + /* = 0xce */ {UNDEFINED, 0, 0}, + /* = 0xcf */ {UNDEFINED, 0, 0}, + /* = 0xd0 */ {UNDEFINED, 0, 0}, + /* = 0xd1 */ {UNDEFINED, 0, 0}, + /* = 0xd2 */ {UNDEFINED, 0, 0}, + /* = 0xd3 */ {UNDEFINED, 0, 0}, + /* = 0xd4 */ {UNDEFINED, 0, 0}, + /* = 0xd5 */ {UNDEFINED, 0, 0}, + /* = 0xd6 */ {UNDEFINED, 0, 0}, + /* = 0xd7 */ {UNDEFINED, 0, 0}, + /* = 0xd8 */ {UNDEFINED, 0, 0}, + /* = 0xd9 */ {UNDEFINED, 0, 0}, + /* = 0xda */ {UNDEFINED, 0, 0}, + /* = 0xdb */ {UNDEFINED, 0, 0}, + /* = 0xdc */ {UNDEFINED, 0, 0}, + /* = 0xdd */ {UNDEFINED, 0, 0}, + /* = 0xde */ {UNDEFINED, 0, 0}, + /* = 0xdf */ {UNDEFINED, 0, 0}, + /* = 0xe0 */ {UNDEFINED, 0, 0}, + /* = 0xe1 */ {UNDEFINED, 0, 0}, + /* = 0xe2 */ {UNDEFINED, 0, 0}, + /* = 0xe3 */ {UNDEFINED, 0, 0}, + /* = 0xe4 */ {UNDEFINED, 0, 0}, + /* = 0xe5 */ {UNDEFINED, 0, 0}, + /* = 0xe6 */ {UNDEFINED, 0, 0}, + /* = 0xe7 */ {UNDEFINED, 0, 0}, + /* = 0xe8 */ {UNDEFINED, 0, 0}, + /* = 0xe9 */ {UNDEFINED, 0, 0}, + /* = 0xea */ {UNDEFINED, 0, 0}, + /* = 0xeb */ {UNDEFINED, 0, 0}, + /* = 0xec */ {UNDEFINED, 0, 0}, + /* = 0xed */ {UNDEFINED, 0, 0}, + /* = 0xee */ {UNDEFINED, 0, 0}, + /* = 0xef */ {UNDEFINED, 0, 0}, + /* CREATE = 0xf0 */ {32000, 3, 1}, + /* CALL = 0xf1 */ {700, 7, 1}, + /* CALLCODE = 0xf2 */ {700, 7, 1}, + /* RETURN = 0xf3 */ {ZERO, 2, 0}, + /* DELEGATECALL = 0xf4 */ {700, 6, 1}, + /* = 0xf5 */ {UNDEFINED, 0, 0}, + /* = 0xf6 */ {UNDEFINED, 0, 0}, + /* = 0xf7 */ {UNDEFINED, 0, 0}, + /* = 0xf8 */ {UNDEFINED, 0, 0}, + /* = 0xf9 */ {UNDEFINED, 0, 0}, + /* STATICCALL = 0xfa */ {700, 6, 1}, + /* = 0xfb */ {UNDEFINED, 0, 0}, + /* = 0xfc */ {UNDEFINED, 0, 0}, + /* REVERT = 0xfd */ {ZERO, 2, 0}, + /* INVALID = 0xfe */ {ZERO, 0, 0}, + /* SUICIDE = 0xff */ {5000, 1, 0}, +}; + +static struct evmc_instruction_metrics byzantium_metrics[256] = { + /* STOP = 0x00 */ {ZERO, 0, 0}, + /* ADD = 0x01 */ {VERYLOW, 2, 1}, + /* MUL = 0x02 */ {LOW, 2, 1}, + /* SUB = 0x03 */ {VERYLOW, 2, 1}, + /* DIV = 0x04 */ {LOW, 2, 1}, + /* SDIV = 0x05 */ {LOW, 2, 1}, + /* MOD = 0x06 */ {LOW, 2, 1}, + /* SMOD = 0x07 */ {LOW, 2, 1}, + /* ADDMOD = 0x08 */ {MID, 3, 1}, + /* MULMOD = 0x09 */ {MID, 3, 1}, + /* EXP = 0x0a */ {10, 2, 1}, + /* SIGNEXTEND = 0x0b */ {LOW, 2, 1}, + /* = 0x0c */ {UNDEFINED, 0, 0}, + /* = 0x0d */ {UNDEFINED, 0, 0}, + /* = 0x0e */ {UNDEFINED, 0, 0}, + /* = 0x0f */ {UNDEFINED, 0, 0}, + /* LT = 0x10 */ {VERYLOW, 2, 1}, + /* GT = 0x11 */ {VERYLOW, 2, 1}, + /* SLT = 0x12 */ {VERYLOW, 2, 1}, + /* SGT = 0x13 */ {VERYLOW, 2, 1}, + /* EQ = 0x14 */ {VERYLOW, 2, 1}, + /* ISZERO = 0x15 */ {VERYLOW, 1, 1}, + /* AND = 0x16 */ {VERYLOW, 2, 1}, + /* OR = 0x17 */ {VERYLOW, 2, 1}, + /* XOR = 0x18 */ {VERYLOW, 2, 1}, + /* NOT = 0x19 */ {VERYLOW, 1, 1}, + /* BYTE = 0x1a */ {VERYLOW, 2, 1}, + /* = 0x1b */ {UNDEFINED, 0, 0}, + /* = 0x1c */ {UNDEFINED, 0, 0}, + /* = 0x1d */ {UNDEFINED, 0, 0}, + /* = 0x1e */ {UNDEFINED, 0, 0}, + /* = 0x1f */ {UNDEFINED, 0, 0}, + /* SHA3 = 0x20 */ {30, 2, 1}, + /* = 0x21 */ {UNDEFINED, 0, 0}, + /* = 0x22 */ {UNDEFINED, 0, 0}, + /* = 0x23 */ {UNDEFINED, 0, 0}, + /* = 0x24 */ {UNDEFINED, 0, 0}, + /* = 0x25 */ {UNDEFINED, 0, 0}, + /* = 0x26 */ {UNDEFINED, 0, 0}, + /* = 0x27 */ {UNDEFINED, 0, 0}, + /* = 0x28 */ {UNDEFINED, 0, 0}, + /* = 0x29 */ {UNDEFINED, 0, 0}, + /* = 0x2a */ {UNDEFINED, 0, 0}, + /* = 0x2b */ {UNDEFINED, 0, 0}, + /* = 0x2c */ {UNDEFINED, 0, 0}, + /* = 0x2d */ {UNDEFINED, 0, 0}, + /* = 0x2e */ {UNDEFINED, 0, 0}, + /* = 0x2f */ {UNDEFINED, 0, 0}, + /* ADDRESS = 0x30 */ {BASE, 0, 1}, + /* BALANCE = 0x31 */ {400, 1, 1}, + /* ORIGIN = 0x32 */ {BASE, 0, 1}, + /* CALLER = 0x33 */ {BASE, 0, 1}, + /* CALLVALUE = 0x34 */ {BASE, 0, 1}, + /* CALLDATALOAD = 0x35 */ {VERYLOW, 1, 1}, + /* CALLDATASIZE = 0x36 */ {BASE, 0, 1}, + /* CALLDATACOPY = 0x37 */ {VERYLOW, 3, 0}, + /* CODESIZE = 0x38 */ {BASE, 0, 1}, + /* CODECOPY = 0x39 */ {VERYLOW, 3, 0}, + /* GASPRICE = 0x3a */ {BASE, 0, 1}, + /* EXTCODESIZE = 0x3b */ {700, 1, 1}, + /* EXTCODECOPY = 0x3c */ {700, 4, 0}, + /* RETURNDATASIZE = 0x3d */ {BASE, 0, 1}, + /* RETURNDATACOPY = 0x3e */ {VERYLOW, 3, 0}, + /* = 0x3f */ {UNDEFINED, 0, 0}, + /* BLOCKHASH = 0x40 */ {20, 1, 1}, + /* COINBASE = 0x41 */ {BASE, 0, 1}, + /* TIMESTAMP = 0x42 */ {BASE, 0, 1}, + /* NUMBER = 0x43 */ {BASE, 0, 1}, + /* DIFFICULTY = 0x44 */ {BASE, 0, 1}, + /* GASLIMIT = 0x45 */ {BASE, 0, 1}, + /* = 0x46 */ {UNDEFINED, 0, 0}, + /* = 0x47 */ {UNDEFINED, 0, 0}, + /* = 0x48 */ {UNDEFINED, 0, 0}, + /* = 0x49 */ {UNDEFINED, 0, 0}, + /* = 0x4a */ {UNDEFINED, 0, 0}, + /* = 0x4b */ {UNDEFINED, 0, 0}, + /* = 0x4c */ {UNDEFINED, 0, 0}, + /* = 0x4d */ {UNDEFINED, 0, 0}, + /* = 0x4e */ {UNDEFINED, 0, 0}, + /* = 0x4f */ {UNDEFINED, 0, 0}, + /* POP = 0x50 */ {BASE, 1, 0}, + /* MLOAD = 0x51 */ {VERYLOW, 1, 1}, + /* MSTORE = 0x52 */ {VERYLOW, 2, 0}, + /* MSTORE8 = 0x53 */ {VERYLOW, 2, 0}, + /* SLOAD = 0x54 */ {200, 1, 1}, + /* SSTORE = 0x55 */ {0, 2, 0}, + /* JUMP = 0x56 */ {MID, 1, 0}, + /* JUMPI = 0x57 */ {HIGH, 2, 0}, + /* PC = 0x58 */ {BASE, 0, 1}, + /* MSIZE = 0x59 */ {BASE, 0, 1}, + /* GAS = 0x5a */ {BASE, 0, 1}, + /* JUMPDEST = 0x5b */ {1, 0, 0}, + /* = 0x5c */ {UNDEFINED, 0, 0}, + /* = 0x5d */ {UNDEFINED, 0, 0}, + /* = 0x5e */ {UNDEFINED, 0, 0}, + /* = 0x5f */ {UNDEFINED, 0, 0}, + /* PUSH1 = 0x60 */ {VERYLOW, 0, 1}, + /* PUSH2 = 0x61 */ {VERYLOW, 0, 1}, + /* PUSH3 = 0x62 */ {VERYLOW, 0, 1}, + /* PUSH4 = 0x63 */ {VERYLOW, 0, 1}, + /* PUSH5 = 0x64 */ {VERYLOW, 0, 1}, + /* PUSH6 = 0x65 */ {VERYLOW, 0, 1}, + /* PUSH7 = 0x66 */ {VERYLOW, 0, 1}, + /* PUSH8 = 0x67 */ {VERYLOW, 0, 1}, + /* PUSH9 = 0x68 */ {VERYLOW, 0, 1}, + /* PUSH10 = 0x69 */ {VERYLOW, 0, 1}, + /* PUSH11 = 0x6a */ {VERYLOW, 0, 1}, + /* PUSH12 = 0x6b */ {VERYLOW, 0, 1}, + /* PUSH13 = 0x6c */ {VERYLOW, 0, 1}, + /* PUSH14 = 0x6d */ {VERYLOW, 0, 1}, + /* PUSH15 = 0x6e */ {VERYLOW, 0, 1}, + /* PUSH16 = 0x6f */ {VERYLOW, 0, 1}, + /* PUSH17 = 0x70 */ {VERYLOW, 0, 1}, + /* PUSH18 = 0x71 */ {VERYLOW, 0, 1}, + /* PUSH19 = 0x72 */ {VERYLOW, 0, 1}, + /* PUSH20 = 0x73 */ {VERYLOW, 0, 1}, + /* PUSH21 = 0x74 */ {VERYLOW, 0, 1}, + /* PUSH22 = 0x75 */ {VERYLOW, 0, 1}, + /* PUSH23 = 0x76 */ {VERYLOW, 0, 1}, + /* PUSH24 = 0x77 */ {VERYLOW, 0, 1}, + /* PUSH25 = 0x78 */ {VERYLOW, 0, 1}, + /* PUSH26 = 0x79 */ {VERYLOW, 0, 1}, + /* PUSH27 = 0x7a */ {VERYLOW, 0, 1}, + /* PUSH28 = 0x7b */ {VERYLOW, 0, 1}, + /* PUSH29 = 0x7c */ {VERYLOW, 0, 1}, + /* PUSH30 = 0x7d */ {VERYLOW, 0, 1}, + /* PUSH31 = 0x7e */ {VERYLOW, 0, 1}, + /* PUSH32 = 0x7f */ {VERYLOW, 0, 1}, + /* DUP1 = 0x80 */ {VERYLOW, 1, 2}, + /* DUP2 = 0x81 */ {VERYLOW, 2, 3}, + /* DUP3 = 0x82 */ {VERYLOW, 3, 4}, + /* DUP4 = 0x83 */ {VERYLOW, 4, 5}, + /* DUP5 = 0x84 */ {VERYLOW, 5, 6}, + /* DUP6 = 0x85 */ {VERYLOW, 6, 7}, + /* DUP7 = 0x86 */ {VERYLOW, 7, 8}, + /* DUP8 = 0x87 */ {VERYLOW, 8, 9}, + /* DUP9 = 0x88 */ {VERYLOW, 9, 10}, + /* DUP10 = 0x89 */ {VERYLOW, 10, 11}, + /* DUP11 = 0x8a */ {VERYLOW, 11, 12}, + /* DUP12 = 0x8b */ {VERYLOW, 12, 13}, + /* DUP13 = 0x8c */ {VERYLOW, 13, 14}, + /* DUP14 = 0x8d */ {VERYLOW, 14, 15}, + /* DUP15 = 0x8e */ {VERYLOW, 15, 16}, + /* DUP16 = 0x8f */ {VERYLOW, 16, 17}, + /* SWAP1 = 0x90 */ {VERYLOW, 2, 2}, + /* SWAP2 = 0x91 */ {VERYLOW, 3, 3}, + /* SWAP3 = 0x92 */ {VERYLOW, 4, 4}, + /* SWAP4 = 0x93 */ {VERYLOW, 5, 5}, + /* SWAP5 = 0x94 */ {VERYLOW, 6, 6}, + /* SWAP6 = 0x95 */ {VERYLOW, 7, 7}, + /* SWAP7 = 0x96 */ {VERYLOW, 8, 8}, + /* SWAP8 = 0x97 */ {VERYLOW, 9, 9}, + /* SWAP9 = 0x98 */ {VERYLOW, 10, 10}, + /* SWAP10 = 0x99 */ {VERYLOW, 11, 11}, + /* SWAP11 = 0x9a */ {VERYLOW, 12, 12}, + /* SWAP12 = 0x9b */ {VERYLOW, 13, 13}, + /* SWAP13 = 0x9c */ {VERYLOW, 14, 14}, + /* SWAP14 = 0x9d */ {VERYLOW, 15, 15}, + /* SWAP15 = 0x9e */ {VERYLOW, 16, 16}, + /* SWAP16 = 0x9f */ {VERYLOW, 17, 17}, + /* LOG0 = 0xa0 */ {1 * 375, 2, 0}, + /* LOG1 = 0xa1 */ {2 * 375, 3, 0}, + /* LOG2 = 0xa2 */ {3 * 375, 4, 0}, + /* LOG3 = 0xa3 */ {4 * 375, 5, 0}, + /* LOG4 = 0xa4 */ {5 * 375, 6, 0}, + /* = 0xa5 */ {UNDEFINED, 0, 0}, + /* = 0xa6 */ {UNDEFINED, 0, 0}, + /* = 0xa7 */ {UNDEFINED, 0, 0}, + /* = 0xa8 */ {UNDEFINED, 0, 0}, + /* = 0xa9 */ {UNDEFINED, 0, 0}, + /* = 0xaa */ {UNDEFINED, 0, 0}, + /* = 0xab */ {UNDEFINED, 0, 0}, + /* = 0xac */ {UNDEFINED, 0, 0}, + /* = 0xad */ {UNDEFINED, 0, 0}, + /* = 0xae */ {UNDEFINED, 0, 0}, + /* = 0xaf */ {UNDEFINED, 0, 0}, + /* = 0xb0 */ {UNDEFINED, 0, 0}, + /* = 0xb1 */ {UNDEFINED, 0, 0}, + /* = 0xb2 */ {UNDEFINED, 0, 0}, + /* = 0xb3 */ {UNDEFINED, 0, 0}, + /* = 0xb4 */ {UNDEFINED, 0, 0}, + /* = 0xb5 */ {UNDEFINED, 0, 0}, + /* = 0xb6 */ {UNDEFINED, 0, 0}, + /* = 0xb7 */ {UNDEFINED, 0, 0}, + /* = 0xb8 */ {UNDEFINED, 0, 0}, + /* = 0xb9 */ {UNDEFINED, 0, 0}, + /* = 0xba */ {UNDEFINED, 0, 0}, + /* = 0xbb */ {UNDEFINED, 0, 0}, + /* = 0xbc */ {UNDEFINED, 0, 0}, + /* = 0xbd */ {UNDEFINED, 0, 0}, + /* = 0xbe */ {UNDEFINED, 0, 0}, + /* = 0xbf */ {UNDEFINED, 0, 0}, + /* = 0xc0 */ {UNDEFINED, 0, 0}, + /* = 0xc1 */ {UNDEFINED, 0, 0}, + /* = 0xc2 */ {UNDEFINED, 0, 0}, + /* = 0xc3 */ {UNDEFINED, 0, 0}, + /* = 0xc4 */ {UNDEFINED, 0, 0}, + /* = 0xc5 */ {UNDEFINED, 0, 0}, + /* = 0xc6 */ {UNDEFINED, 0, 0}, + /* = 0xc7 */ {UNDEFINED, 0, 0}, + /* = 0xc8 */ {UNDEFINED, 0, 0}, + /* = 0xc9 */ {UNDEFINED, 0, 0}, + /* = 0xca */ {UNDEFINED, 0, 0}, + /* = 0xcb */ {UNDEFINED, 0, 0}, + /* = 0xcc */ {UNDEFINED, 0, 0}, + /* = 0xcd */ {UNDEFINED, 0, 0}, + /* = 0xce */ {UNDEFINED, 0, 0}, + /* = 0xcf */ {UNDEFINED, 0, 0}, + /* = 0xd0 */ {UNDEFINED, 0, 0}, + /* = 0xd1 */ {UNDEFINED, 0, 0}, + /* = 0xd2 */ {UNDEFINED, 0, 0}, + /* = 0xd3 */ {UNDEFINED, 0, 0}, + /* = 0xd4 */ {UNDEFINED, 0, 0}, + /* = 0xd5 */ {UNDEFINED, 0, 0}, + /* = 0xd6 */ {UNDEFINED, 0, 0}, + /* = 0xd7 */ {UNDEFINED, 0, 0}, + /* = 0xd8 */ {UNDEFINED, 0, 0}, + /* = 0xd9 */ {UNDEFINED, 0, 0}, + /* = 0xda */ {UNDEFINED, 0, 0}, + /* = 0xdb */ {UNDEFINED, 0, 0}, + /* = 0xdc */ {UNDEFINED, 0, 0}, + /* = 0xdd */ {UNDEFINED, 0, 0}, + /* = 0xde */ {UNDEFINED, 0, 0}, + /* = 0xdf */ {UNDEFINED, 0, 0}, + /* = 0xe0 */ {UNDEFINED, 0, 0}, + /* = 0xe1 */ {UNDEFINED, 0, 0}, + /* = 0xe2 */ {UNDEFINED, 0, 0}, + /* = 0xe3 */ {UNDEFINED, 0, 0}, + /* = 0xe4 */ {UNDEFINED, 0, 0}, + /* = 0xe5 */ {UNDEFINED, 0, 0}, + /* = 0xe6 */ {UNDEFINED, 0, 0}, + /* = 0xe7 */ {UNDEFINED, 0, 0}, + /* = 0xe8 */ {UNDEFINED, 0, 0}, + /* = 0xe9 */ {UNDEFINED, 0, 0}, + /* = 0xea */ {UNDEFINED, 0, 0}, + /* = 0xeb */ {UNDEFINED, 0, 0}, + /* = 0xec */ {UNDEFINED, 0, 0}, + /* = 0xed */ {UNDEFINED, 0, 0}, + /* = 0xee */ {UNDEFINED, 0, 0}, + /* = 0xef */ {UNDEFINED, 0, 0}, + /* CREATE = 0xf0 */ {32000, 3, 1}, + /* CALL = 0xf1 */ {700, 7, 1}, + /* CALLCODE = 0xf2 */ {700, 7, 1}, + /* RETURN = 0xf3 */ {ZERO, 2, 0}, + /* DELEGATECALL = 0xf4 */ {700, 6, 1}, + /* = 0xf5 */ {UNDEFINED, 0, 0}, + /* = 0xf6 */ {UNDEFINED, 0, 0}, + /* = 0xf7 */ {UNDEFINED, 0, 0}, + /* = 0xf8 */ {UNDEFINED, 0, 0}, + /* = 0xf9 */ {UNDEFINED, 0, 0}, + /* STATICCALL = 0xfa */ {700, 6, 1}, + /* = 0xfb */ {UNDEFINED, 0, 0}, + /* = 0xfc */ {UNDEFINED, 0, 0}, + /* REVERT = 0xfd */ {ZERO, 2, 0}, + /* INVALID = 0xfe */ {ZERO, 0, 0}, + /* SUICIDE = 0xff */ {5000, 1, 0}, +}; + +static struct evmc_instruction_metrics tangerine_whistle_metrics[256] = { + /* STOP = 0x00 */ {ZERO, 0, 0}, + /* ADD = 0x01 */ {VERYLOW, 2, 1}, + /* MUL = 0x02 */ {LOW, 2, 1}, + /* SUB = 0x03 */ {VERYLOW, 2, 1}, + /* DIV = 0x04 */ {LOW, 2, 1}, + /* SDIV = 0x05 */ {LOW, 2, 1}, + /* MOD = 0x06 */ {LOW, 2, 1}, + /* SMOD = 0x07 */ {LOW, 2, 1}, + /* ADDMOD = 0x08 */ {MID, 3, 1}, + /* MULMOD = 0x09 */ {MID, 3, 1}, + /* EXP = 0x0a */ {10, 2, 1}, + /* SIGNEXTEND = 0x0b */ {LOW, 2, 1}, + /* = 0x0c */ {UNDEFINED, 0, 0}, + /* = 0x0d */ {UNDEFINED, 0, 0}, + /* = 0x0e */ {UNDEFINED, 0, 0}, + /* = 0x0f */ {UNDEFINED, 0, 0}, + /* LT = 0x10 */ {VERYLOW, 2, 1}, + /* GT = 0x11 */ {VERYLOW, 2, 1}, + /* SLT = 0x12 */ {VERYLOW, 2, 1}, + /* SGT = 0x13 */ {VERYLOW, 2, 1}, + /* EQ = 0x14 */ {VERYLOW, 2, 1}, + /* ISZERO = 0x15 */ {VERYLOW, 1, 1}, + /* AND = 0x16 */ {VERYLOW, 2, 1}, + /* OR = 0x17 */ {VERYLOW, 2, 1}, + /* XOR = 0x18 */ {VERYLOW, 2, 1}, + /* NOT = 0x19 */ {VERYLOW, 1, 1}, + /* BYTE = 0x1a */ {VERYLOW, 2, 1}, + /* = 0x1b */ {UNDEFINED, 0, 0}, + /* = 0x1c */ {UNDEFINED, 0, 0}, + /* = 0x1d */ {UNDEFINED, 0, 0}, + /* = 0x1e */ {UNDEFINED, 0, 0}, + /* = 0x1f */ {UNDEFINED, 0, 0}, + /* SHA3 = 0x20 */ {30, 2, 1}, + /* = 0x21 */ {UNDEFINED, 0, 0}, + /* = 0x22 */ {UNDEFINED, 0, 0}, + /* = 0x23 */ {UNDEFINED, 0, 0}, + /* = 0x24 */ {UNDEFINED, 0, 0}, + /* = 0x25 */ {UNDEFINED, 0, 0}, + /* = 0x26 */ {UNDEFINED, 0, 0}, + /* = 0x27 */ {UNDEFINED, 0, 0}, + /* = 0x28 */ {UNDEFINED, 0, 0}, + /* = 0x29 */ {UNDEFINED, 0, 0}, + /* = 0x2a */ {UNDEFINED, 0, 0}, + /* = 0x2b */ {UNDEFINED, 0, 0}, + /* = 0x2c */ {UNDEFINED, 0, 0}, + /* = 0x2d */ {UNDEFINED, 0, 0}, + /* = 0x2e */ {UNDEFINED, 0, 0}, + /* = 0x2f */ {UNDEFINED, 0, 0}, + /* ADDRESS = 0x30 */ {BASE, 0, 1}, + /* BALANCE = 0x31 */ {400, 1, 1}, + /* ORIGIN = 0x32 */ {BASE, 0, 1}, + /* CALLER = 0x33 */ {BASE, 0, 1}, + /* CALLVALUE = 0x34 */ {BASE, 0, 1}, + /* CALLDATALOAD = 0x35 */ {VERYLOW, 1, 1}, + /* CALLDATASIZE = 0x36 */ {BASE, 0, 1}, + /* CALLDATACOPY = 0x37 */ {VERYLOW, 3, 0}, + /* CODESIZE = 0x38 */ {BASE, 0, 1}, + /* CODECOPY = 0x39 */ {VERYLOW, 3, 0}, + /* GASPRICE = 0x3a */ {BASE, 0, 1}, + /* EXTCODESIZE = 0x3b */ {700, 1, 1}, + /* EXTCODECOPY = 0x3c */ {700, 4, 0}, + /* = 0x3d */ {UNDEFINED, 0, 0}, + /* = 0x3e */ {UNDEFINED, 0, 0}, + /* = 0x3f */ {UNDEFINED, 0, 0}, + /* BLOCKHASH = 0x40 */ {20, 1, 1}, + /* COINBASE = 0x41 */ {BASE, 0, 1}, + /* TIMESTAMP = 0x42 */ {BASE, 0, 1}, + /* NUMBER = 0x43 */ {BASE, 0, 1}, + /* DIFFICULTY = 0x44 */ {BASE, 0, 1}, + /* GASLIMIT = 0x45 */ {BASE, 0, 1}, + /* = 0x46 */ {UNDEFINED, 0, 0}, + /* = 0x47 */ {UNDEFINED, 0, 0}, + /* = 0x48 */ {UNDEFINED, 0, 0}, + /* = 0x49 */ {UNDEFINED, 0, 0}, + /* = 0x4a */ {UNDEFINED, 0, 0}, + /* = 0x4b */ {UNDEFINED, 0, 0}, + /* = 0x4c */ {UNDEFINED, 0, 0}, + /* = 0x4d */ {UNDEFINED, 0, 0}, + /* = 0x4e */ {UNDEFINED, 0, 0}, + /* = 0x4f */ {UNDEFINED, 0, 0}, + /* POP = 0x50 */ {BASE, 1, 0}, + /* MLOAD = 0x51 */ {VERYLOW, 1, 1}, + /* MSTORE = 0x52 */ {VERYLOW, 2, 0}, + /* MSTORE8 = 0x53 */ {VERYLOW, 2, 0}, + /* SLOAD = 0x54 */ {200, 1, 1}, + /* SSTORE = 0x55 */ {0, 2, 0}, + /* JUMP = 0x56 */ {MID, 1, 0}, + /* JUMPI = 0x57 */ {HIGH, 2, 0}, + /* PC = 0x58 */ {BASE, 0, 1}, + /* MSIZE = 0x59 */ {BASE, 0, 1}, + /* GAS = 0x5a */ {BASE, 0, 1}, + /* JUMPDEST = 0x5b */ {1, 0, 0}, + /* = 0x5c */ {UNDEFINED, 0, 0}, + /* = 0x5d */ {UNDEFINED, 0, 0}, + /* = 0x5e */ {UNDEFINED, 0, 0}, + /* = 0x5f */ {UNDEFINED, 0, 0}, + /* PUSH1 = 0x60 */ {VERYLOW, 0, 1}, + /* PUSH2 = 0x61 */ {VERYLOW, 0, 1}, + /* PUSH3 = 0x62 */ {VERYLOW, 0, 1}, + /* PUSH4 = 0x63 */ {VERYLOW, 0, 1}, + /* PUSH5 = 0x64 */ {VERYLOW, 0, 1}, + /* PUSH6 = 0x65 */ {VERYLOW, 0, 1}, + /* PUSH7 = 0x66 */ {VERYLOW, 0, 1}, + /* PUSH8 = 0x67 */ {VERYLOW, 0, 1}, + /* PUSH9 = 0x68 */ {VERYLOW, 0, 1}, + /* PUSH10 = 0x69 */ {VERYLOW, 0, 1}, + /* PUSH11 = 0x6a */ {VERYLOW, 0, 1}, + /* PUSH12 = 0x6b */ {VERYLOW, 0, 1}, + /* PUSH13 = 0x6c */ {VERYLOW, 0, 1}, + /* PUSH14 = 0x6d */ {VERYLOW, 0, 1}, + /* PUSH15 = 0x6e */ {VERYLOW, 0, 1}, + /* PUSH16 = 0x6f */ {VERYLOW, 0, 1}, + /* PUSH17 = 0x70 */ {VERYLOW, 0, 1}, + /* PUSH18 = 0x71 */ {VERYLOW, 0, 1}, + /* PUSH19 = 0x72 */ {VERYLOW, 0, 1}, + /* PUSH20 = 0x73 */ {VERYLOW, 0, 1}, + /* PUSH21 = 0x74 */ {VERYLOW, 0, 1}, + /* PUSH22 = 0x75 */ {VERYLOW, 0, 1}, + /* PUSH23 = 0x76 */ {VERYLOW, 0, 1}, + /* PUSH24 = 0x77 */ {VERYLOW, 0, 1}, + /* PUSH25 = 0x78 */ {VERYLOW, 0, 1}, + /* PUSH26 = 0x79 */ {VERYLOW, 0, 1}, + /* PUSH27 = 0x7a */ {VERYLOW, 0, 1}, + /* PUSH28 = 0x7b */ {VERYLOW, 0, 1}, + /* PUSH29 = 0x7c */ {VERYLOW, 0, 1}, + /* PUSH30 = 0x7d */ {VERYLOW, 0, 1}, + /* PUSH31 = 0x7e */ {VERYLOW, 0, 1}, + /* PUSH32 = 0x7f */ {VERYLOW, 0, 1}, + /* DUP1 = 0x80 */ {VERYLOW, 1, 2}, + /* DUP2 = 0x81 */ {VERYLOW, 2, 3}, + /* DUP3 = 0x82 */ {VERYLOW, 3, 4}, + /* DUP4 = 0x83 */ {VERYLOW, 4, 5}, + /* DUP5 = 0x84 */ {VERYLOW, 5, 6}, + /* DUP6 = 0x85 */ {VERYLOW, 6, 7}, + /* DUP7 = 0x86 */ {VERYLOW, 7, 8}, + /* DUP8 = 0x87 */ {VERYLOW, 8, 9}, + /* DUP9 = 0x88 */ {VERYLOW, 9, 10}, + /* DUP10 = 0x89 */ {VERYLOW, 10, 11}, + /* DUP11 = 0x8a */ {VERYLOW, 11, 12}, + /* DUP12 = 0x8b */ {VERYLOW, 12, 13}, + /* DUP13 = 0x8c */ {VERYLOW, 13, 14}, + /* DUP14 = 0x8d */ {VERYLOW, 14, 15}, + /* DUP15 = 0x8e */ {VERYLOW, 15, 16}, + /* DUP16 = 0x8f */ {VERYLOW, 16, 17}, + /* SWAP1 = 0x90 */ {VERYLOW, 2, 2}, + /* SWAP2 = 0x91 */ {VERYLOW, 3, 3}, + /* SWAP3 = 0x92 */ {VERYLOW, 4, 4}, + /* SWAP4 = 0x93 */ {VERYLOW, 5, 5}, + /* SWAP5 = 0x94 */ {VERYLOW, 6, 6}, + /* SWAP6 = 0x95 */ {VERYLOW, 7, 7}, + /* SWAP7 = 0x96 */ {VERYLOW, 8, 8}, + /* SWAP8 = 0x97 */ {VERYLOW, 9, 9}, + /* SWAP9 = 0x98 */ {VERYLOW, 10, 10}, + /* SWAP10 = 0x99 */ {VERYLOW, 11, 11}, + /* SWAP11 = 0x9a */ {VERYLOW, 12, 12}, + /* SWAP12 = 0x9b */ {VERYLOW, 13, 13}, + /* SWAP13 = 0x9c */ {VERYLOW, 14, 14}, + /* SWAP14 = 0x9d */ {VERYLOW, 15, 15}, + /* SWAP15 = 0x9e */ {VERYLOW, 16, 16}, + /* SWAP16 = 0x9f */ {VERYLOW, 17, 17}, + /* LOG0 = 0xa0 */ {1 * 375, 2, 0}, + /* LOG1 = 0xa1 */ {2 * 375, 3, 0}, + /* LOG2 = 0xa2 */ {3 * 375, 4, 0}, + /* LOG3 = 0xa3 */ {4 * 375, 5, 0}, + /* LOG4 = 0xa4 */ {5 * 375, 6, 0}, + /* = 0xa5 */ {UNDEFINED, 0, 0}, + /* = 0xa6 */ {UNDEFINED, 0, 0}, + /* = 0xa7 */ {UNDEFINED, 0, 0}, + /* = 0xa8 */ {UNDEFINED, 0, 0}, + /* = 0xa9 */ {UNDEFINED, 0, 0}, + /* = 0xaa */ {UNDEFINED, 0, 0}, + /* = 0xab */ {UNDEFINED, 0, 0}, + /* = 0xac */ {UNDEFINED, 0, 0}, + /* = 0xad */ {UNDEFINED, 0, 0}, + /* = 0xae */ {UNDEFINED, 0, 0}, + /* = 0xaf */ {UNDEFINED, 0, 0}, + /* = 0xb0 */ {UNDEFINED, 0, 0}, + /* = 0xb1 */ {UNDEFINED, 0, 0}, + /* = 0xb2 */ {UNDEFINED, 0, 0}, + /* = 0xb3 */ {UNDEFINED, 0, 0}, + /* = 0xb4 */ {UNDEFINED, 0, 0}, + /* = 0xb5 */ {UNDEFINED, 0, 0}, + /* = 0xb6 */ {UNDEFINED, 0, 0}, + /* = 0xb7 */ {UNDEFINED, 0, 0}, + /* = 0xb8 */ {UNDEFINED, 0, 0}, + /* = 0xb9 */ {UNDEFINED, 0, 0}, + /* = 0xba */ {UNDEFINED, 0, 0}, + /* = 0xbb */ {UNDEFINED, 0, 0}, + /* = 0xbc */ {UNDEFINED, 0, 0}, + /* = 0xbd */ {UNDEFINED, 0, 0}, + /* = 0xbe */ {UNDEFINED, 0, 0}, + /* = 0xbf */ {UNDEFINED, 0, 0}, + /* = 0xc0 */ {UNDEFINED, 0, 0}, + /* = 0xc1 */ {UNDEFINED, 0, 0}, + /* = 0xc2 */ {UNDEFINED, 0, 0}, + /* = 0xc3 */ {UNDEFINED, 0, 0}, + /* = 0xc4 */ {UNDEFINED, 0, 0}, + /* = 0xc5 */ {UNDEFINED, 0, 0}, + /* = 0xc6 */ {UNDEFINED, 0, 0}, + /* = 0xc7 */ {UNDEFINED, 0, 0}, + /* = 0xc8 */ {UNDEFINED, 0, 0}, + /* = 0xc9 */ {UNDEFINED, 0, 0}, + /* = 0xca */ {UNDEFINED, 0, 0}, + /* = 0xcb */ {UNDEFINED, 0, 0}, + /* = 0xcc */ {UNDEFINED, 0, 0}, + /* = 0xcd */ {UNDEFINED, 0, 0}, + /* = 0xce */ {UNDEFINED, 0, 0}, + /* = 0xcf */ {UNDEFINED, 0, 0}, + /* = 0xd0 */ {UNDEFINED, 0, 0}, + /* = 0xd1 */ {UNDEFINED, 0, 0}, + /* = 0xd2 */ {UNDEFINED, 0, 0}, + /* = 0xd3 */ {UNDEFINED, 0, 0}, + /* = 0xd4 */ {UNDEFINED, 0, 0}, + /* = 0xd5 */ {UNDEFINED, 0, 0}, + /* = 0xd6 */ {UNDEFINED, 0, 0}, + /* = 0xd7 */ {UNDEFINED, 0, 0}, + /* = 0xd8 */ {UNDEFINED, 0, 0}, + /* = 0xd9 */ {UNDEFINED, 0, 0}, + /* = 0xda */ {UNDEFINED, 0, 0}, + /* = 0xdb */ {UNDEFINED, 0, 0}, + /* = 0xdc */ {UNDEFINED, 0, 0}, + /* = 0xdd */ {UNDEFINED, 0, 0}, + /* = 0xde */ {UNDEFINED, 0, 0}, + /* = 0xdf */ {UNDEFINED, 0, 0}, + /* = 0xe0 */ {UNDEFINED, 0, 0}, + /* = 0xe1 */ {UNDEFINED, 0, 0}, + /* = 0xe2 */ {UNDEFINED, 0, 0}, + /* = 0xe3 */ {UNDEFINED, 0, 0}, + /* = 0xe4 */ {UNDEFINED, 0, 0}, + /* = 0xe5 */ {UNDEFINED, 0, 0}, + /* = 0xe6 */ {UNDEFINED, 0, 0}, + /* = 0xe7 */ {UNDEFINED, 0, 0}, + /* = 0xe8 */ {UNDEFINED, 0, 0}, + /* = 0xe9 */ {UNDEFINED, 0, 0}, + /* = 0xea */ {UNDEFINED, 0, 0}, + /* = 0xeb */ {UNDEFINED, 0, 0}, + /* = 0xec */ {UNDEFINED, 0, 0}, + /* = 0xed */ {UNDEFINED, 0, 0}, + /* = 0xee */ {UNDEFINED, 0, 0}, + /* = 0xef */ {UNDEFINED, 0, 0}, + /* CREATE = 0xf0 */ {32000, 3, 1}, + /* CALL = 0xf1 */ {700, 7, 1}, + /* CALLCODE = 0xf2 */ {700, 7, 1}, + /* RETURN = 0xf3 */ {ZERO, 2, 0}, + /* DELEGATECALL = 0xf4 */ {700, 6, 1}, + /* = 0xf5 */ {UNDEFINED, 0, 0}, + /* = 0xf6 */ {UNDEFINED, 0, 0}, + /* = 0xf7 */ {UNDEFINED, 0, 0}, + /* = 0xf8 */ {UNDEFINED, 0, 0}, + /* = 0xf9 */ {UNDEFINED, 0, 0}, + /* = 0xfa */ {UNDEFINED, 0, 0}, + /* = 0xfb */ {UNDEFINED, 0, 0}, + /* = 0xfc */ {UNDEFINED, 0, 0}, + /* = 0xfd */ {UNDEFINED, 0, 0}, + /* INVALID = 0xfe */ {ZERO, 0, 0}, + /* SUICIDE = 0xff */ {5000, 1, 0}, +}; + +static struct evmc_instruction_metrics homestead_metrics[256] = { + /* STOP = 0x00 */ {ZERO, 0, 0}, + /* ADD = 0x01 */ {VERYLOW, 2, 1}, + /* MUL = 0x02 */ {LOW, 2, 1}, + /* SUB = 0x03 */ {VERYLOW, 2, 1}, + /* DIV = 0x04 */ {LOW, 2, 1}, + /* SDIV = 0x05 */ {LOW, 2, 1}, + /* MOD = 0x06 */ {LOW, 2, 1}, + /* SMOD = 0x07 */ {LOW, 2, 1}, + /* ADDMOD = 0x08 */ {MID, 3, 1}, + /* MULMOD = 0x09 */ {MID, 3, 1}, + /* EXP = 0x0a */ {10, 2, 1}, + /* SIGNEXTEND = 0x0b */ {LOW, 2, 1}, + /* = 0x0c */ {UNDEFINED, 0, 0}, + /* = 0x0d */ {UNDEFINED, 0, 0}, + /* = 0x0e */ {UNDEFINED, 0, 0}, + /* = 0x0f */ {UNDEFINED, 0, 0}, + /* LT = 0x10 */ {VERYLOW, 2, 1}, + /* GT = 0x11 */ {VERYLOW, 2, 1}, + /* SLT = 0x12 */ {VERYLOW, 2, 1}, + /* SGT = 0x13 */ {VERYLOW, 2, 1}, + /* EQ = 0x14 */ {VERYLOW, 2, 1}, + /* ISZERO = 0x15 */ {VERYLOW, 1, 1}, + /* AND = 0x16 */ {VERYLOW, 2, 1}, + /* OR = 0x17 */ {VERYLOW, 2, 1}, + /* XOR = 0x18 */ {VERYLOW, 2, 1}, + /* NOT = 0x19 */ {VERYLOW, 1, 1}, + /* BYTE = 0x1a */ {VERYLOW, 2, 1}, + /* = 0x1b */ {UNDEFINED, 0, 0}, + /* = 0x1c */ {UNDEFINED, 0, 0}, + /* = 0x1d */ {UNDEFINED, 0, 0}, + /* = 0x1e */ {UNDEFINED, 0, 0}, + /* = 0x1f */ {UNDEFINED, 0, 0}, + /* SHA3 = 0x20 */ {30, 2, 1}, + /* = 0x21 */ {UNDEFINED, 0, 0}, + /* = 0x22 */ {UNDEFINED, 0, 0}, + /* = 0x23 */ {UNDEFINED, 0, 0}, + /* = 0x24 */ {UNDEFINED, 0, 0}, + /* = 0x25 */ {UNDEFINED, 0, 0}, + /* = 0x26 */ {UNDEFINED, 0, 0}, + /* = 0x27 */ {UNDEFINED, 0, 0}, + /* = 0x28 */ {UNDEFINED, 0, 0}, + /* = 0x29 */ {UNDEFINED, 0, 0}, + /* = 0x2a */ {UNDEFINED, 0, 0}, + /* = 0x2b */ {UNDEFINED, 0, 0}, + /* = 0x2c */ {UNDEFINED, 0, 0}, + /* = 0x2d */ {UNDEFINED, 0, 0}, + /* = 0x2e */ {UNDEFINED, 0, 0}, + /* = 0x2f */ {UNDEFINED, 0, 0}, + /* ADDRESS = 0x30 */ {BASE, 0, 1}, + /* BALANCE = 0x31 */ {20, 1, 1}, + /* ORIGIN = 0x32 */ {BASE, 0, 1}, + /* CALLER = 0x33 */ {BASE, 0, 1}, + /* CALLVALUE = 0x34 */ {BASE, 0, 1}, + /* CALLDATALOAD = 0x35 */ {VERYLOW, 1, 1}, + /* CALLDATASIZE = 0x36 */ {BASE, 0, 1}, + /* CALLDATACOPY = 0x37 */ {VERYLOW, 3, 0}, + /* CODESIZE = 0x38 */ {BASE, 0, 1}, + /* CODECOPY = 0x39 */ {VERYLOW, 3, 0}, + /* GASPRICE = 0x3a */ {BASE, 0, 1}, + /* EXTCODESIZE = 0x3b */ {20, 1, 1}, + /* EXTCODECOPY = 0x3c */ {20, 4, 0}, + /* = 0x3d */ {UNDEFINED, 0, 0}, + /* = 0x3e */ {UNDEFINED, 0, 0}, + /* = 0x3f */ {UNDEFINED, 0, 0}, + /* BLOCKHASH = 0x40 */ {20, 1, 1}, + /* COINBASE = 0x41 */ {BASE, 0, 1}, + /* TIMESTAMP = 0x42 */ {BASE, 0, 1}, + /* NUMBER = 0x43 */ {BASE, 0, 1}, + /* DIFFICULTY = 0x44 */ {BASE, 0, 1}, + /* GASLIMIT = 0x45 */ {BASE, 0, 1}, + /* = 0x46 */ {UNDEFINED, 0, 0}, + /* = 0x47 */ {UNDEFINED, 0, 0}, + /* = 0x48 */ {UNDEFINED, 0, 0}, + /* = 0x49 */ {UNDEFINED, 0, 0}, + /* = 0x4a */ {UNDEFINED, 0, 0}, + /* = 0x4b */ {UNDEFINED, 0, 0}, + /* = 0x4c */ {UNDEFINED, 0, 0}, + /* = 0x4d */ {UNDEFINED, 0, 0}, + /* = 0x4e */ {UNDEFINED, 0, 0}, + /* = 0x4f */ {UNDEFINED, 0, 0}, + /* POP = 0x50 */ {BASE, 1, 0}, + /* MLOAD = 0x51 */ {VERYLOW, 1, 1}, + /* MSTORE = 0x52 */ {VERYLOW, 2, 0}, + /* MSTORE8 = 0x53 */ {VERYLOW, 2, 0}, + /* SLOAD = 0x54 */ {50, 1, 1}, + /* SSTORE = 0x55 */ {0, 2, 0}, + /* JUMP = 0x56 */ {MID, 1, 0}, + /* JUMPI = 0x57 */ {HIGH, 2, 0}, + /* PC = 0x58 */ {BASE, 0, 1}, + /* MSIZE = 0x59 */ {BASE, 0, 1}, + /* GAS = 0x5a */ {BASE, 0, 1}, + /* JUMPDEST = 0x5b */ {1, 0, 0}, + /* = 0x5c */ {UNDEFINED, 0, 0}, + /* = 0x5d */ {UNDEFINED, 0, 0}, + /* = 0x5e */ {UNDEFINED, 0, 0}, + /* = 0x5f */ {UNDEFINED, 0, 0}, + /* PUSH1 = 0x60 */ {VERYLOW, 0, 1}, + /* PUSH2 = 0x61 */ {VERYLOW, 0, 1}, + /* PUSH3 = 0x62 */ {VERYLOW, 0, 1}, + /* PUSH4 = 0x63 */ {VERYLOW, 0, 1}, + /* PUSH5 = 0x64 */ {VERYLOW, 0, 1}, + /* PUSH6 = 0x65 */ {VERYLOW, 0, 1}, + /* PUSH7 = 0x66 */ {VERYLOW, 0, 1}, + /* PUSH8 = 0x67 */ {VERYLOW, 0, 1}, + /* PUSH9 = 0x68 */ {VERYLOW, 0, 1}, + /* PUSH10 = 0x69 */ {VERYLOW, 0, 1}, + /* PUSH11 = 0x6a */ {VERYLOW, 0, 1}, + /* PUSH12 = 0x6b */ {VERYLOW, 0, 1}, + /* PUSH13 = 0x6c */ {VERYLOW, 0, 1}, + /* PUSH14 = 0x6d */ {VERYLOW, 0, 1}, + /* PUSH15 = 0x6e */ {VERYLOW, 0, 1}, + /* PUSH16 = 0x6f */ {VERYLOW, 0, 1}, + /* PUSH17 = 0x70 */ {VERYLOW, 0, 1}, + /* PUSH18 = 0x71 */ {VERYLOW, 0, 1}, + /* PUSH19 = 0x72 */ {VERYLOW, 0, 1}, + /* PUSH20 = 0x73 */ {VERYLOW, 0, 1}, + /* PUSH21 = 0x74 */ {VERYLOW, 0, 1}, + /* PUSH22 = 0x75 */ {VERYLOW, 0, 1}, + /* PUSH23 = 0x76 */ {VERYLOW, 0, 1}, + /* PUSH24 = 0x77 */ {VERYLOW, 0, 1}, + /* PUSH25 = 0x78 */ {VERYLOW, 0, 1}, + /* PUSH26 = 0x79 */ {VERYLOW, 0, 1}, + /* PUSH27 = 0x7a */ {VERYLOW, 0, 1}, + /* PUSH28 = 0x7b */ {VERYLOW, 0, 1}, + /* PUSH29 = 0x7c */ {VERYLOW, 0, 1}, + /* PUSH30 = 0x7d */ {VERYLOW, 0, 1}, + /* PUSH31 = 0x7e */ {VERYLOW, 0, 1}, + /* PUSH32 = 0x7f */ {VERYLOW, 0, 1}, + /* DUP1 = 0x80 */ {VERYLOW, 1, 2}, + /* DUP2 = 0x81 */ {VERYLOW, 2, 3}, + /* DUP3 = 0x82 */ {VERYLOW, 3, 4}, + /* DUP4 = 0x83 */ {VERYLOW, 4, 5}, + /* DUP5 = 0x84 */ {VERYLOW, 5, 6}, + /* DUP6 = 0x85 */ {VERYLOW, 6, 7}, + /* DUP7 = 0x86 */ {VERYLOW, 7, 8}, + /* DUP8 = 0x87 */ {VERYLOW, 8, 9}, + /* DUP9 = 0x88 */ {VERYLOW, 9, 10}, + /* DUP10 = 0x89 */ {VERYLOW, 10, 11}, + /* DUP11 = 0x8a */ {VERYLOW, 11, 12}, + /* DUP12 = 0x8b */ {VERYLOW, 12, 13}, + /* DUP13 = 0x8c */ {VERYLOW, 13, 14}, + /* DUP14 = 0x8d */ {VERYLOW, 14, 15}, + /* DUP15 = 0x8e */ {VERYLOW, 15, 16}, + /* DUP16 = 0x8f */ {VERYLOW, 16, 17}, + /* SWAP1 = 0x90 */ {VERYLOW, 2, 2}, + /* SWAP2 = 0x91 */ {VERYLOW, 3, 3}, + /* SWAP3 = 0x92 */ {VERYLOW, 4, 4}, + /* SWAP4 = 0x93 */ {VERYLOW, 5, 5}, + /* SWAP5 = 0x94 */ {VERYLOW, 6, 6}, + /* SWAP6 = 0x95 */ {VERYLOW, 7, 7}, + /* SWAP7 = 0x96 */ {VERYLOW, 8, 8}, + /* SWAP8 = 0x97 */ {VERYLOW, 9, 9}, + /* SWAP9 = 0x98 */ {VERYLOW, 10, 10}, + /* SWAP10 = 0x99 */ {VERYLOW, 11, 11}, + /* SWAP11 = 0x9a */ {VERYLOW, 12, 12}, + /* SWAP12 = 0x9b */ {VERYLOW, 13, 13}, + /* SWAP13 = 0x9c */ {VERYLOW, 14, 14}, + /* SWAP14 = 0x9d */ {VERYLOW, 15, 15}, + /* SWAP15 = 0x9e */ {VERYLOW, 16, 16}, + /* SWAP16 = 0x9f */ {VERYLOW, 17, 17}, + /* LOG0 = 0xa0 */ {1 * 375, 2, 0}, + /* LOG1 = 0xa1 */ {2 * 375, 3, 0}, + /* LOG2 = 0xa2 */ {3 * 375, 4, 0}, + /* LOG3 = 0xa3 */ {4 * 375, 5, 0}, + /* LOG4 = 0xa4 */ {5 * 375, 6, 0}, + /* = 0xa5 */ {UNDEFINED, 0, 0}, + /* = 0xa6 */ {UNDEFINED, 0, 0}, + /* = 0xa7 */ {UNDEFINED, 0, 0}, + /* = 0xa8 */ {UNDEFINED, 0, 0}, + /* = 0xa9 */ {UNDEFINED, 0, 0}, + /* = 0xaa */ {UNDEFINED, 0, 0}, + /* = 0xab */ {UNDEFINED, 0, 0}, + /* = 0xac */ {UNDEFINED, 0, 0}, + /* = 0xad */ {UNDEFINED, 0, 0}, + /* = 0xae */ {UNDEFINED, 0, 0}, + /* = 0xaf */ {UNDEFINED, 0, 0}, + /* = 0xb0 */ {UNDEFINED, 0, 0}, + /* = 0xb1 */ {UNDEFINED, 0, 0}, + /* = 0xb2 */ {UNDEFINED, 0, 0}, + /* = 0xb3 */ {UNDEFINED, 0, 0}, + /* = 0xb4 */ {UNDEFINED, 0, 0}, + /* = 0xb5 */ {UNDEFINED, 0, 0}, + /* = 0xb6 */ {UNDEFINED, 0, 0}, + /* = 0xb7 */ {UNDEFINED, 0, 0}, + /* = 0xb8 */ {UNDEFINED, 0, 0}, + /* = 0xb9 */ {UNDEFINED, 0, 0}, + /* = 0xba */ {UNDEFINED, 0, 0}, + /* = 0xbb */ {UNDEFINED, 0, 0}, + /* = 0xbc */ {UNDEFINED, 0, 0}, + /* = 0xbd */ {UNDEFINED, 0, 0}, + /* = 0xbe */ {UNDEFINED, 0, 0}, + /* = 0xbf */ {UNDEFINED, 0, 0}, + /* = 0xc0 */ {UNDEFINED, 0, 0}, + /* = 0xc1 */ {UNDEFINED, 0, 0}, + /* = 0xc2 */ {UNDEFINED, 0, 0}, + /* = 0xc3 */ {UNDEFINED, 0, 0}, + /* = 0xc4 */ {UNDEFINED, 0, 0}, + /* = 0xc5 */ {UNDEFINED, 0, 0}, + /* = 0xc6 */ {UNDEFINED, 0, 0}, + /* = 0xc7 */ {UNDEFINED, 0, 0}, + /* = 0xc8 */ {UNDEFINED, 0, 0}, + /* = 0xc9 */ {UNDEFINED, 0, 0}, + /* = 0xca */ {UNDEFINED, 0, 0}, + /* = 0xcb */ {UNDEFINED, 0, 0}, + /* = 0xcc */ {UNDEFINED, 0, 0}, + /* = 0xcd */ {UNDEFINED, 0, 0}, + /* = 0xce */ {UNDEFINED, 0, 0}, + /* = 0xcf */ {UNDEFINED, 0, 0}, + /* = 0xd0 */ {UNDEFINED, 0, 0}, + /* = 0xd1 */ {UNDEFINED, 0, 0}, + /* = 0xd2 */ {UNDEFINED, 0, 0}, + /* = 0xd3 */ {UNDEFINED, 0, 0}, + /* = 0xd4 */ {UNDEFINED, 0, 0}, + /* = 0xd5 */ {UNDEFINED, 0, 0}, + /* = 0xd6 */ {UNDEFINED, 0, 0}, + /* = 0xd7 */ {UNDEFINED, 0, 0}, + /* = 0xd8 */ {UNDEFINED, 0, 0}, + /* = 0xd9 */ {UNDEFINED, 0, 0}, + /* = 0xda */ {UNDEFINED, 0, 0}, + /* = 0xdb */ {UNDEFINED, 0, 0}, + /* = 0xdc */ {UNDEFINED, 0, 0}, + /* = 0xdd */ {UNDEFINED, 0, 0}, + /* = 0xde */ {UNDEFINED, 0, 0}, + /* = 0xdf */ {UNDEFINED, 0, 0}, + /* = 0xe0 */ {UNDEFINED, 0, 0}, + /* = 0xe1 */ {UNDEFINED, 0, 0}, + /* = 0xe2 */ {UNDEFINED, 0, 0}, + /* = 0xe3 */ {UNDEFINED, 0, 0}, + /* = 0xe4 */ {UNDEFINED, 0, 0}, + /* = 0xe5 */ {UNDEFINED, 0, 0}, + /* = 0xe6 */ {UNDEFINED, 0, 0}, + /* = 0xe7 */ {UNDEFINED, 0, 0}, + /* = 0xe8 */ {UNDEFINED, 0, 0}, + /* = 0xe9 */ {UNDEFINED, 0, 0}, + /* = 0xea */ {UNDEFINED, 0, 0}, + /* = 0xeb */ {UNDEFINED, 0, 0}, + /* = 0xec */ {UNDEFINED, 0, 0}, + /* = 0xed */ {UNDEFINED, 0, 0}, + /* = 0xee */ {UNDEFINED, 0, 0}, + /* = 0xef */ {UNDEFINED, 0, 0}, + /* CREATE = 0xf0 */ {32000, 3, 1}, + /* CALL = 0xf1 */ {40, 7, 1}, + /* CALLCODE = 0xf2 */ {40, 7, 1}, + /* RETURN = 0xf3 */ {ZERO, 2, 0}, + /* DELEGATECALL = 0xf4 */ {40, 6, 1}, + /* = 0xf5 */ {UNDEFINED, 0, 0}, + /* = 0xf6 */ {UNDEFINED, 0, 0}, + /* = 0xf7 */ {UNDEFINED, 0, 0}, + /* = 0xf8 */ {UNDEFINED, 0, 0}, + /* = 0xf9 */ {UNDEFINED, 0, 0}, + /* = 0xfa */ {UNDEFINED, 0, 0}, + /* = 0xfb */ {UNDEFINED, 0, 0}, + /* = 0xfc */ {UNDEFINED, 0, 0}, + /* = 0xfd */ {UNDEFINED, 0, 0}, + /* INVALID = 0xfe */ {ZERO, 0, 0}, + /* SUICIDE = 0xff */ {ZERO, 1, 0}, +}; + +static struct evmc_instruction_metrics frontier_metrics[256] = { + /* STOP = 0x00 */ {ZERO, 0, 0}, + /* ADD = 0x01 */ {VERYLOW, 2, 1}, + /* MUL = 0x02 */ {LOW, 2, 1}, + /* SUB = 0x03 */ {VERYLOW, 2, 1}, + /* DIV = 0x04 */ {LOW, 2, 1}, + /* SDIV = 0x05 */ {LOW, 2, 1}, + /* MOD = 0x06 */ {LOW, 2, 1}, + /* SMOD = 0x07 */ {LOW, 2, 1}, + /* ADDMOD = 0x08 */ {MID, 3, 1}, + /* MULMOD = 0x09 */ {MID, 3, 1}, + /* EXP = 0x0a */ {10, 2, 1}, + /* SIGNEXTEND = 0x0b */ {LOW, 2, 1}, + /* = 0x0c */ {UNDEFINED, 0, 0}, + /* = 0x0d */ {UNDEFINED, 0, 0}, + /* = 0x0e */ {UNDEFINED, 0, 0}, + /* = 0x0f */ {UNDEFINED, 0, 0}, + /* LT = 0x10 */ {VERYLOW, 2, 1}, + /* GT = 0x11 */ {VERYLOW, 2, 1}, + /* SLT = 0x12 */ {VERYLOW, 2, 1}, + /* SGT = 0x13 */ {VERYLOW, 2, 1}, + /* EQ = 0x14 */ {VERYLOW, 2, 1}, + /* ISZERO = 0x15 */ {VERYLOW, 1, 1}, + /* AND = 0x16 */ {VERYLOW, 2, 1}, + /* OR = 0x17 */ {VERYLOW, 2, 1}, + /* XOR = 0x18 */ {VERYLOW, 2, 1}, + /* NOT = 0x19 */ {VERYLOW, 1, 1}, + /* BYTE = 0x1a */ {VERYLOW, 2, 1}, + /* = 0x1b */ {UNDEFINED, 0, 0}, + /* = 0x1c */ {UNDEFINED, 0, 0}, + /* = 0x1d */ {UNDEFINED, 0, 0}, + /* = 0x1e */ {UNDEFINED, 0, 0}, + /* = 0x1f */ {UNDEFINED, 0, 0}, + /* SHA3 = 0x20 */ {30, 2, 1}, + /* = 0x21 */ {UNDEFINED, 0, 0}, + /* = 0x22 */ {UNDEFINED, 0, 0}, + /* = 0x23 */ {UNDEFINED, 0, 0}, + /* = 0x24 */ {UNDEFINED, 0, 0}, + /* = 0x25 */ {UNDEFINED, 0, 0}, + /* = 0x26 */ {UNDEFINED, 0, 0}, + /* = 0x27 */ {UNDEFINED, 0, 0}, + /* = 0x28 */ {UNDEFINED, 0, 0}, + /* = 0x29 */ {UNDEFINED, 0, 0}, + /* = 0x2a */ {UNDEFINED, 0, 0}, + /* = 0x2b */ {UNDEFINED, 0, 0}, + /* = 0x2c */ {UNDEFINED, 0, 0}, + /* = 0x2d */ {UNDEFINED, 0, 0}, + /* = 0x2e */ {UNDEFINED, 0, 0}, + /* = 0x2f */ {UNDEFINED, 0, 0}, + /* ADDRESS = 0x30 */ {BASE, 0, 1}, + /* BALANCE = 0x31 */ {20, 1, 1}, + /* ORIGIN = 0x32 */ {BASE, 0, 1}, + /* CALLER = 0x33 */ {BASE, 0, 1}, + /* CALLVALUE = 0x34 */ {BASE, 0, 1}, + /* CALLDATALOAD = 0x35 */ {VERYLOW, 1, 1}, + /* CALLDATASIZE = 0x36 */ {BASE, 0, 1}, + /* CALLDATACOPY = 0x37 */ {VERYLOW, 3, 0}, + /* CODESIZE = 0x38 */ {BASE, 0, 1}, + /* CODECOPY = 0x39 */ {VERYLOW, 3, 0}, + /* GASPRICE = 0x3a */ {BASE, 0, 1}, + /* EXTCODESIZE = 0x3b */ {20, 1, 1}, + /* EXTCODECOPY = 0x3c */ {20, 4, 0}, + /* = 0x3d */ {UNDEFINED, 0, 0}, + /* = 0x3e */ {UNDEFINED, 0, 0}, + /* = 0x3f */ {UNDEFINED, 0, 0}, + /* BLOCKHASH = 0x40 */ {20, 1, 1}, + /* COINBASE = 0x41 */ {BASE, 0, 1}, + /* TIMESTAMP = 0x42 */ {BASE, 0, 1}, + /* NUMBER = 0x43 */ {BASE, 0, 1}, + /* DIFFICULTY = 0x44 */ {BASE, 0, 1}, + /* GASLIMIT = 0x45 */ {BASE, 0, 1}, + /* = 0x46 */ {UNDEFINED, 0, 0}, + /* = 0x47 */ {UNDEFINED, 0, 0}, + /* = 0x48 */ {UNDEFINED, 0, 0}, + /* = 0x49 */ {UNDEFINED, 0, 0}, + /* = 0x4a */ {UNDEFINED, 0, 0}, + /* = 0x4b */ {UNDEFINED, 0, 0}, + /* = 0x4c */ {UNDEFINED, 0, 0}, + /* = 0x4d */ {UNDEFINED, 0, 0}, + /* = 0x4e */ {UNDEFINED, 0, 0}, + /* = 0x4f */ {UNDEFINED, 0, 0}, + /* POP = 0x50 */ {BASE, 1, 0}, + /* MLOAD = 0x51 */ {VERYLOW, 1, 1}, + /* MSTORE = 0x52 */ {VERYLOW, 2, 0}, + /* MSTORE8 = 0x53 */ {VERYLOW, 2, 0}, + /* SLOAD = 0x54 */ {50, 1, 1}, + /* SSTORE = 0x55 */ {0, 2, 0}, + /* JUMP = 0x56 */ {MID, 1, 0}, + /* JUMPI = 0x57 */ {HIGH, 2, 0}, + /* PC = 0x58 */ {BASE, 0, 1}, + /* MSIZE = 0x59 */ {BASE, 0, 1}, + /* GAS = 0x5a */ {BASE, 0, 1}, + /* JUMPDEST = 0x5b */ {1, 0, 0}, + /* = 0x5c */ {UNDEFINED, 0, 0}, + /* = 0x5d */ {UNDEFINED, 0, 0}, + /* = 0x5e */ {UNDEFINED, 0, 0}, + /* = 0x5f */ {UNDEFINED, 0, 0}, + /* PUSH1 = 0x60 */ {VERYLOW, 0, 1}, + /* PUSH2 = 0x61 */ {VERYLOW, 0, 1}, + /* PUSH3 = 0x62 */ {VERYLOW, 0, 1}, + /* PUSH4 = 0x63 */ {VERYLOW, 0, 1}, + /* PUSH5 = 0x64 */ {VERYLOW, 0, 1}, + /* PUSH6 = 0x65 */ {VERYLOW, 0, 1}, + /* PUSH7 = 0x66 */ {VERYLOW, 0, 1}, + /* PUSH8 = 0x67 */ {VERYLOW, 0, 1}, + /* PUSH9 = 0x68 */ {VERYLOW, 0, 1}, + /* PUSH10 = 0x69 */ {VERYLOW, 0, 1}, + /* PUSH11 = 0x6a */ {VERYLOW, 0, 1}, + /* PUSH12 = 0x6b */ {VERYLOW, 0, 1}, + /* PUSH13 = 0x6c */ {VERYLOW, 0, 1}, + /* PUSH14 = 0x6d */ {VERYLOW, 0, 1}, + /* PUSH15 = 0x6e */ {VERYLOW, 0, 1}, + /* PUSH16 = 0x6f */ {VERYLOW, 0, 1}, + /* PUSH17 = 0x70 */ {VERYLOW, 0, 1}, + /* PUSH18 = 0x71 */ {VERYLOW, 0, 1}, + /* PUSH19 = 0x72 */ {VERYLOW, 0, 1}, + /* PUSH20 = 0x73 */ {VERYLOW, 0, 1}, + /* PUSH21 = 0x74 */ {VERYLOW, 0, 1}, + /* PUSH22 = 0x75 */ {VERYLOW, 0, 1}, + /* PUSH23 = 0x76 */ {VERYLOW, 0, 1}, + /* PUSH24 = 0x77 */ {VERYLOW, 0, 1}, + /* PUSH25 = 0x78 */ {VERYLOW, 0, 1}, + /* PUSH26 = 0x79 */ {VERYLOW, 0, 1}, + /* PUSH27 = 0x7a */ {VERYLOW, 0, 1}, + /* PUSH28 = 0x7b */ {VERYLOW, 0, 1}, + /* PUSH29 = 0x7c */ {VERYLOW, 0, 1}, + /* PUSH30 = 0x7d */ {VERYLOW, 0, 1}, + /* PUSH31 = 0x7e */ {VERYLOW, 0, 1}, + /* PUSH32 = 0x7f */ {VERYLOW, 0, 1}, + /* DUP1 = 0x80 */ {VERYLOW, 1, 2}, + /* DUP2 = 0x81 */ {VERYLOW, 2, 3}, + /* DUP3 = 0x82 */ {VERYLOW, 3, 4}, + /* DUP4 = 0x83 */ {VERYLOW, 4, 5}, + /* DUP5 = 0x84 */ {VERYLOW, 5, 6}, + /* DUP6 = 0x85 */ {VERYLOW, 6, 7}, + /* DUP7 = 0x86 */ {VERYLOW, 7, 8}, + /* DUP8 = 0x87 */ {VERYLOW, 8, 9}, + /* DUP9 = 0x88 */ {VERYLOW, 9, 10}, + /* DUP10 = 0x89 */ {VERYLOW, 10, 11}, + /* DUP11 = 0x8a */ {VERYLOW, 11, 12}, + /* DUP12 = 0x8b */ {VERYLOW, 12, 13}, + /* DUP13 = 0x8c */ {VERYLOW, 13, 14}, + /* DUP14 = 0x8d */ {VERYLOW, 14, 15}, + /* DUP15 = 0x8e */ {VERYLOW, 15, 16}, + /* DUP16 = 0x8f */ {VERYLOW, 16, 17}, + /* SWAP1 = 0x90 */ {VERYLOW, 2, 2}, + /* SWAP2 = 0x91 */ {VERYLOW, 3, 3}, + /* SWAP3 = 0x92 */ {VERYLOW, 4, 4}, + /* SWAP4 = 0x93 */ {VERYLOW, 5, 5}, + /* SWAP5 = 0x94 */ {VERYLOW, 6, 6}, + /* SWAP6 = 0x95 */ {VERYLOW, 7, 7}, + /* SWAP7 = 0x96 */ {VERYLOW, 8, 8}, + /* SWAP8 = 0x97 */ {VERYLOW, 9, 9}, + /* SWAP9 = 0x98 */ {VERYLOW, 10, 10}, + /* SWAP10 = 0x99 */ {VERYLOW, 11, 11}, + /* SWAP11 = 0x9a */ {VERYLOW, 12, 12}, + /* SWAP12 = 0x9b */ {VERYLOW, 13, 13}, + /* SWAP13 = 0x9c */ {VERYLOW, 14, 14}, + /* SWAP14 = 0x9d */ {VERYLOW, 15, 15}, + /* SWAP15 = 0x9e */ {VERYLOW, 16, 16}, + /* SWAP16 = 0x9f */ {VERYLOW, 17, 17}, + /* LOG0 = 0xa0 */ {1 * 375, 2, 0}, + /* LOG1 = 0xa1 */ {2 * 375, 3, 0}, + /* LOG2 = 0xa2 */ {3 * 375, 4, 0}, + /* LOG3 = 0xa3 */ {4 * 375, 5, 0}, + /* LOG4 = 0xa4 */ {5 * 375, 6, 0}, + /* = 0xa5 */ {UNDEFINED, 0, 0}, + /* = 0xa6 */ {UNDEFINED, 0, 0}, + /* = 0xa7 */ {UNDEFINED, 0, 0}, + /* = 0xa8 */ {UNDEFINED, 0, 0}, + /* = 0xa9 */ {UNDEFINED, 0, 0}, + /* = 0xaa */ {UNDEFINED, 0, 0}, + /* = 0xab */ {UNDEFINED, 0, 0}, + /* = 0xac */ {UNDEFINED, 0, 0}, + /* = 0xad */ {UNDEFINED, 0, 0}, + /* = 0xae */ {UNDEFINED, 0, 0}, + /* = 0xaf */ {UNDEFINED, 0, 0}, + /* = 0xb0 */ {UNDEFINED, 0, 0}, + /* = 0xb1 */ {UNDEFINED, 0, 0}, + /* = 0xb2 */ {UNDEFINED, 0, 0}, + /* = 0xb3 */ {UNDEFINED, 0, 0}, + /* = 0xb4 */ {UNDEFINED, 0, 0}, + /* = 0xb5 */ {UNDEFINED, 0, 0}, + /* = 0xb6 */ {UNDEFINED, 0, 0}, + /* = 0xb7 */ {UNDEFINED, 0, 0}, + /* = 0xb8 */ {UNDEFINED, 0, 0}, + /* = 0xb9 */ {UNDEFINED, 0, 0}, + /* = 0xba */ {UNDEFINED, 0, 0}, + /* = 0xbb */ {UNDEFINED, 0, 0}, + /* = 0xbc */ {UNDEFINED, 0, 0}, + /* = 0xbd */ {UNDEFINED, 0, 0}, + /* = 0xbe */ {UNDEFINED, 0, 0}, + /* = 0xbf */ {UNDEFINED, 0, 0}, + /* = 0xc0 */ {UNDEFINED, 0, 0}, + /* = 0xc1 */ {UNDEFINED, 0, 0}, + /* = 0xc2 */ {UNDEFINED, 0, 0}, + /* = 0xc3 */ {UNDEFINED, 0, 0}, + /* = 0xc4 */ {UNDEFINED, 0, 0}, + /* = 0xc5 */ {UNDEFINED, 0, 0}, + /* = 0xc6 */ {UNDEFINED, 0, 0}, + /* = 0xc7 */ {UNDEFINED, 0, 0}, + /* = 0xc8 */ {UNDEFINED, 0, 0}, + /* = 0xc9 */ {UNDEFINED, 0, 0}, + /* = 0xca */ {UNDEFINED, 0, 0}, + /* = 0xcb */ {UNDEFINED, 0, 0}, + /* = 0xcc */ {UNDEFINED, 0, 0}, + /* = 0xcd */ {UNDEFINED, 0, 0}, + /* = 0xce */ {UNDEFINED, 0, 0}, + /* = 0xcf */ {UNDEFINED, 0, 0}, + /* = 0xd0 */ {UNDEFINED, 0, 0}, + /* = 0xd1 */ {UNDEFINED, 0, 0}, + /* = 0xd2 */ {UNDEFINED, 0, 0}, + /* = 0xd3 */ {UNDEFINED, 0, 0}, + /* = 0xd4 */ {UNDEFINED, 0, 0}, + /* = 0xd5 */ {UNDEFINED, 0, 0}, + /* = 0xd6 */ {UNDEFINED, 0, 0}, + /* = 0xd7 */ {UNDEFINED, 0, 0}, + /* = 0xd8 */ {UNDEFINED, 0, 0}, + /* = 0xd9 */ {UNDEFINED, 0, 0}, + /* = 0xda */ {UNDEFINED, 0, 0}, + /* = 0xdb */ {UNDEFINED, 0, 0}, + /* = 0xdc */ {UNDEFINED, 0, 0}, + /* = 0xdd */ {UNDEFINED, 0, 0}, + /* = 0xde */ {UNDEFINED, 0, 0}, + /* = 0xdf */ {UNDEFINED, 0, 0}, + /* = 0xe0 */ {UNDEFINED, 0, 0}, + /* = 0xe1 */ {UNDEFINED, 0, 0}, + /* = 0xe2 */ {UNDEFINED, 0, 0}, + /* = 0xe3 */ {UNDEFINED, 0, 0}, + /* = 0xe4 */ {UNDEFINED, 0, 0}, + /* = 0xe5 */ {UNDEFINED, 0, 0}, + /* = 0xe6 */ {UNDEFINED, 0, 0}, + /* = 0xe7 */ {UNDEFINED, 0, 0}, + /* = 0xe8 */ {UNDEFINED, 0, 0}, + /* = 0xe9 */ {UNDEFINED, 0, 0}, + /* = 0xea */ {UNDEFINED, 0, 0}, + /* = 0xeb */ {UNDEFINED, 0, 0}, + /* = 0xec */ {UNDEFINED, 0, 0}, + /* = 0xed */ {UNDEFINED, 0, 0}, + /* = 0xee */ {UNDEFINED, 0, 0}, + /* = 0xef */ {UNDEFINED, 0, 0}, + /* CREATE = 0xf0 */ {32000, 3, 1}, + /* CALL = 0xf1 */ {40, 7, 1}, + /* CALLCODE = 0xf2 */ {40, 7, 1}, + /* RETURN = 0xf3 */ {ZERO, 2, 0}, + /* = 0xf4 */ {UNDEFINED, 0, 0}, + /* = 0xf5 */ {UNDEFINED, 0, 0}, + /* = 0xf6 */ {UNDEFINED, 0, 0}, + /* = 0xf7 */ {UNDEFINED, 0, 0}, + /* = 0xf8 */ {UNDEFINED, 0, 0}, + /* = 0xf9 */ {UNDEFINED, 0, 0}, + /* = 0xfa */ {UNDEFINED, 0, 0}, + /* = 0xfb */ {UNDEFINED, 0, 0}, + /* = 0xfc */ {UNDEFINED, 0, 0}, + /* = 0xfd */ {UNDEFINED, 0, 0}, + /* INVALID = 0xfe */ {ZERO, 0, 0}, + /* SUICIDE = 0xff */ {ZERO, 1, 0}, +}; + +const struct evmc_instruction_metrics* evmc_get_instruction_metrics_table( + enum evmc_revision revision) +{ + switch (revision) + { + case EVMC_CONSTANTINOPLE: + return constantinople_metrics; + case EVMC_BYZANTIUM: + return byzantium_metrics; + case EVMC_SPURIOUS_DRAGON: + case EVMC_TANGERINE_WHISTLE: + return tangerine_whistle_metrics; + case EVMC_HOMESTEAD: + return homestead_metrics; + case EVMC_FRONTIER: + return frontier_metrics; + } + return NULL; +} + + +static const char* names[256] = { + "STOP", + "ADD", + "MUL", + "SUB", + "DIV", + "SDIV", + "MOD", + "SMOD", + "ADDMOD", + "MULMOD", + "EXP", + "SIGNEXTEND", + NULL, + NULL, + NULL, + NULL, + "LT", + "GT", + "SLT", + "SGT", + "EQ", + "ISZERO", + "AND", + "OR", + "XOR", + "NOT", + "BYTE", + "SHL", + "SHR", + "SAR", + NULL, + NULL, + "SHA3", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "ADDRESS", + "BALANCE", + "ORIGIN", + "CALLER", + "CALLVALUE", + "CALLDATALOAD", + "CALLDATASIZE", + "CALLDATACOPY", + "CODESIZE", + "CODECOPY", + "GASPRICE", + "EXTCODESIZE", + "EXTCODECOPY", + "RETURNDATASIZE", + "RETURNDATACOPY", + NULL, + "BLOCKHASH", + "COINBASE", + "TIMESTAMP", + "NUMBER", + "DIFFICULTY", + "GASLIMIT", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "POP", + "MLOAD", + "MSTORE", + "MSTORE8", + "SLOAD", + "SSTORE", + "JUMP", + "JUMPI", + "PC", + "MSIZE", + "GAS", + "JUMPDEST", + NULL, + NULL, + NULL, + NULL, + "PUSH1", + "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", + "DUP2", + "DUP3", + "DUP4", + "DUP5", + "DUP6", + "DUP7", + "DUP8", + "DUP9", + "DUP10", + "DUP11", + "DUP12", + "DUP13", + "DUP14", + "DUP15", + "DUP16", + "SWAP1", + "SWAP2", + "SWAP3", + "SWAP4", + "SWAP5", + "SWAP6", + "SWAP7", + "SWAP8", + "SWAP9", + "SWAP10", + "SWAP11", + "SWAP12", + "SWAP13", + "SWAP14", + "SWAP15", + "SWAP16", + "LOG0", + "LOG1", + "LOG2", + "LOG3", + "LOG4", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "CREATE", + "CALL", + "CALLCODE", + "RETURN", + "DELEGATECALL", + NULL, + NULL, + NULL, + NULL, + NULL, + "STATICCALL", + NULL, + NULL, + "REVERT", + "INVALID", + "SUICIDE", +}; + +const char* const* evmc_get_instruction_name_table() +{ + return names; +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7b791370f..207f5299e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -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) diff --git a/test/unittests/CMakeLists.txt b/test/unittests/CMakeLists.txt new file mode 100644 index 000000000..cdd3b315d --- /dev/null +++ b/test/unittests/CMakeLists.txt @@ -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 ..) diff --git a/test/unittests/test_instructions.cpp b/test/unittests/test_instructions.cpp new file mode 100644 index 000000000..0f6858d81 --- /dev/null +++ b/test/unittests/test_instructions.cpp @@ -0,0 +1,37 @@ +// EVMC: Ethereum Client-VM Connector API. +// Copyright 2018 Pawel Bylica. +// Licensed under the MIT License. See the LICENSE file. + +#include + +#include + +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); +} \ No newline at end of file diff --git a/test/vmtester/CMakeLists.txt b/test/vmtester/CMakeLists.txt index 01464ece6..a579dad52 100644 --- a/test/vmtester/CMakeLists.txt +++ b/test/vmtester/CMakeLists.txt @@ -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(