Merge pull request #354 from ethereum/istanbul_instruction_tables

Add separate Istanbul instruction tables
This commit is contained in:
Paweł Bylica 2019-07-23 13:16:08 +02:00 committed by GitHub
commit b8ae6d24f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 661 additions and 17 deletions

View File

@ -21,6 +21,265 @@
/** @} */ /** @} */
static struct evmc_instruction_metrics istanbul_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 */ {HIGH, 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},
/* EXTCODEHASH = 0x3f */ {400, 1, 1},
/* 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},
/* CREATE2 = 0xf5 */ {32000, 4, 1},
/* = 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 constantinople_metrics[256] = { static struct evmc_instruction_metrics constantinople_metrics[256] = {
/* STOP = 0x00 */ {ZERO, 0, 0}, /* STOP = 0x00 */ {ZERO, 0, 0},
/* ADD = 0x01 */ {VERYLOW, 2, 1}, /* ADD = 0x01 */ {VERYLOW, 2, 1},
@ -1322,6 +1581,7 @@ const struct evmc_instruction_metrics* evmc_get_instruction_metrics_table(
switch (revision) switch (revision)
{ {
case EVMC_ISTANBUL: case EVMC_ISTANBUL:
return istanbul_metrics;
case EVMC_PETERSBURG: case EVMC_PETERSBURG:
case EVMC_CONSTANTINOPLE: case EVMC_CONSTANTINOPLE:
return constantinople_metrics; return constantinople_metrics;

View File

@ -5,6 +5,265 @@
#include <evmc/instructions.h> #include <evmc/instructions.h>
static const char* istanbul_names[256] = {
/* 0x00 */ "STOP",
/* 0x01 */ "ADD",
/* 0x02 */ "MUL",
/* 0x03 */ "SUB",
/* 0x04 */ "DIV",
/* 0x05 */ "SDIV",
/* 0x06 */ "MOD",
/* 0x07 */ "SMOD",
/* 0x08 */ "ADDMOD",
/* 0x09 */ "MULMOD",
/* 0x0a */ "EXP",
/* 0x0b */ "SIGNEXTEND",
/* 0x0c */ NULL,
/* 0x0d */ NULL,
/* 0x0e */ NULL,
/* 0x0f */ NULL,
/* 0x10 */ "LT",
/* 0x11 */ "GT",
/* 0x12 */ "SLT",
/* 0x13 */ "SGT",
/* 0x14 */ "EQ",
/* 0x15 */ "ISZERO",
/* 0x16 */ "AND",
/* 0x17 */ "OR",
/* 0x18 */ "XOR",
/* 0x19 */ "NOT",
/* 0x1a */ "BYTE",
/* 0x1b */ "SHL",
/* 0x1c */ "SHR",
/* 0x1d */ "SAR",
/* 0x1e */ NULL,
/* 0x1f */ NULL,
/* 0x20 */ "SHA3",
/* 0x21 */ NULL,
/* 0x22 */ NULL,
/* 0x23 */ NULL,
/* 0x24 */ NULL,
/* 0x25 */ NULL,
/* 0x26 */ NULL,
/* 0x27 */ NULL,
/* 0x28 */ NULL,
/* 0x29 */ NULL,
/* 0x2a */ NULL,
/* 0x2b */ NULL,
/* 0x2c */ NULL,
/* 0x2d */ NULL,
/* 0x2e */ NULL,
/* 0x2f */ NULL,
/* 0x30 */ "ADDRESS",
/* 0x31 */ "BALANCE",
/* 0x32 */ "ORIGIN",
/* 0x33 */ "CALLER",
/* 0x34 */ "CALLVALUE",
/* 0x35 */ "CALLDATALOAD",
/* 0x36 */ "CALLDATASIZE",
/* 0x37 */ "CALLDATACOPY",
/* 0x38 */ "CODESIZE",
/* 0x39 */ "CODECOPY",
/* 0x3a */ "GASPRICE",
/* 0x3b */ "EXTCODESIZE",
/* 0x3c */ "EXTCODECOPY",
/* 0x3d */ "RETURNDATASIZE",
/* 0x3e */ "RETURNDATACOPY",
/* 0x3f */ "EXTCODEHASH",
/* 0x40 */ "BLOCKHASH",
/* 0x41 */ "COINBASE",
/* 0x42 */ "TIMESTAMP",
/* 0x43 */ "NUMBER",
/* 0x44 */ "DIFFICULTY",
/* 0x45 */ "GASLIMIT",
/* 0x46 */ NULL,
/* 0x47 */ NULL,
/* 0x48 */ NULL,
/* 0x49 */ NULL,
/* 0x4a */ NULL,
/* 0x4b */ NULL,
/* 0x4c */ NULL,
/* 0x4d */ NULL,
/* 0x4e */ NULL,
/* 0x4f */ NULL,
/* 0x50 */ "POP",
/* 0x51 */ "MLOAD",
/* 0x52 */ "MSTORE",
/* 0x53 */ "MSTORE8",
/* 0x54 */ "SLOAD",
/* 0x55 */ "SSTORE",
/* 0x56 */ "JUMP",
/* 0x57 */ "JUMPI",
/* 0x58 */ "PC",
/* 0x59 */ "MSIZE",
/* 0x5a */ "GAS",
/* 0x5b */ "JUMPDEST",
/* 0x5c */ NULL,
/* 0x5d */ NULL,
/* 0x5e */ NULL,
/* 0x5f */ NULL,
/* 0x60 */ "PUSH1",
/* 0x61 */ "PUSH2",
/* 0x62 */ "PUSH3",
/* 0x63 */ "PUSH4",
/* 0x64 */ "PUSH5",
/* 0x65 */ "PUSH6",
/* 0x66 */ "PUSH7",
/* 0x67 */ "PUSH8",
/* 0x68 */ "PUSH9",
/* 0x69 */ "PUSH10",
/* 0x6a */ "PUSH11",
/* 0x6b */ "PUSH12",
/* 0x6c */ "PUSH13",
/* 0x6d */ "PUSH14",
/* 0x6e */ "PUSH15",
/* 0x6f */ "PUSH16",
/* 0x70 */ "PUSH17",
/* 0x71 */ "PUSH18",
/* 0x72 */ "PUSH19",
/* 0x73 */ "PUSH20",
/* 0x74 */ "PUSH21",
/* 0x75 */ "PUSH22",
/* 0x76 */ "PUSH23",
/* 0x77 */ "PUSH24",
/* 0x78 */ "PUSH25",
/* 0x79 */ "PUSH26",
/* 0x7a */ "PUSH27",
/* 0x7b */ "PUSH28",
/* 0x7c */ "PUSH29",
/* 0x7d */ "PUSH30",
/* 0x7e */ "PUSH31",
/* 0x7f */ "PUSH32",
/* 0x80 */ "DUP1",
/* 0x81 */ "DUP2",
/* 0x82 */ "DUP3",
/* 0x83 */ "DUP4",
/* 0x84 */ "DUP5",
/* 0x85 */ "DUP6",
/* 0x86 */ "DUP7",
/* 0x87 */ "DUP8",
/* 0x88 */ "DUP9",
/* 0x89 */ "DUP10",
/* 0x8a */ "DUP11",
/* 0x8b */ "DUP12",
/* 0x8c */ "DUP13",
/* 0x8d */ "DUP14",
/* 0x8e */ "DUP15",
/* 0x8f */ "DUP16",
/* 0x90 */ "SWAP1",
/* 0x91 */ "SWAP2",
/* 0x92 */ "SWAP3",
/* 0x93 */ "SWAP4",
/* 0x94 */ "SWAP5",
/* 0x95 */ "SWAP6",
/* 0x96 */ "SWAP7",
/* 0x97 */ "SWAP8",
/* 0x98 */ "SWAP9",
/* 0x99 */ "SWAP10",
/* 0x9a */ "SWAP11",
/* 0x9b */ "SWAP12",
/* 0x9c */ "SWAP13",
/* 0x9d */ "SWAP14",
/* 0x9e */ "SWAP15",
/* 0x9f */ "SWAP16",
/* 0xa0 */ "LOG0",
/* 0xa1 */ "LOG1",
/* 0xa2 */ "LOG2",
/* 0xa3 */ "LOG3",
/* 0xa4 */ "LOG4",
/* 0xa5 */ NULL,
/* 0xa6 */ NULL,
/* 0xa7 */ NULL,
/* 0xa8 */ NULL,
/* 0xa9 */ NULL,
/* 0xaa */ NULL,
/* 0xab */ NULL,
/* 0xac */ NULL,
/* 0xad */ NULL,
/* 0xae */ NULL,
/* 0xaf */ NULL,
/* 0xb0 */ NULL,
/* 0xb1 */ NULL,
/* 0xb2 */ NULL,
/* 0xb3 */ NULL,
/* 0xb4 */ NULL,
/* 0xb5 */ NULL,
/* 0xb6 */ NULL,
/* 0xb7 */ NULL,
/* 0xb8 */ NULL,
/* 0xb9 */ NULL,
/* 0xba */ NULL,
/* 0xbb */ NULL,
/* 0xbc */ NULL,
/* 0xbd */ NULL,
/* 0xbe */ NULL,
/* 0xbf */ NULL,
/* 0xc0 */ NULL,
/* 0xc1 */ NULL,
/* 0xc2 */ NULL,
/* 0xc3 */ NULL,
/* 0xc4 */ NULL,
/* 0xc5 */ NULL,
/* 0xc6 */ NULL,
/* 0xc7 */ NULL,
/* 0xc8 */ NULL,
/* 0xc9 */ NULL,
/* 0xca */ NULL,
/* 0xcb */ NULL,
/* 0xcc */ NULL,
/* 0xcd */ NULL,
/* 0xce */ NULL,
/* 0xcf */ NULL,
/* 0xd0 */ NULL,
/* 0xd1 */ NULL,
/* 0xd2 */ NULL,
/* 0xd3 */ NULL,
/* 0xd4 */ NULL,
/* 0xd5 */ NULL,
/* 0xd6 */ NULL,
/* 0xd7 */ NULL,
/* 0xd8 */ NULL,
/* 0xd9 */ NULL,
/* 0xda */ NULL,
/* 0xdb */ NULL,
/* 0xdc */ NULL,
/* 0xdd */ NULL,
/* 0xde */ NULL,
/* 0xdf */ NULL,
/* 0xe0 */ NULL,
/* 0xe1 */ NULL,
/* 0xe2 */ NULL,
/* 0xe3 */ NULL,
/* 0xe4 */ NULL,
/* 0xe5 */ NULL,
/* 0xe6 */ NULL,
/* 0xe7 */ NULL,
/* 0xe8 */ NULL,
/* 0xe9 */ NULL,
/* 0xea */ NULL,
/* 0xeb */ NULL,
/* 0xec */ NULL,
/* 0xed */ NULL,
/* 0xee */ NULL,
/* 0xef */ NULL,
/* 0xf0 */ "CREATE",
/* 0xf1 */ "CALL",
/* 0xf2 */ "CALLCODE",
/* 0xf3 */ "RETURN",
/* 0xf4 */ "DELEGATECALL",
/* 0xf5 */ "CREATE2",
/* 0xf6 */ NULL,
/* 0xf7 */ NULL,
/* 0xf8 */ NULL,
/* 0xf9 */ NULL,
/* 0xfa */ "STATICCALL",
/* 0xfb */ NULL,
/* 0xfc */ NULL,
/* 0xfd */ "REVERT",
/* 0xfe */ "INVALID",
/* 0xff */ "SELFDESTRUCT",
};
static const char* constantinople_names[256] = { static const char* constantinople_names[256] = {
/* 0x00 */ "STOP", /* 0x00 */ "STOP",
/* 0x01 */ "ADD", /* 0x01 */ "ADD",
@ -1046,6 +1305,7 @@ const char* const* evmc_get_instruction_names_table(enum evmc_revision revision)
switch (revision) switch (revision)
{ {
case EVMC_ISTANBUL: case EVMC_ISTANBUL:
return istanbul_names;
case EVMC_PETERSBURG: case EVMC_PETERSBURG:
case EVMC_CONSTANTINOPLE: case EVMC_CONSTANTINOPLE:
return constantinople_names; return constantinople_names;

View File

@ -6,6 +6,33 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
bool operator==(const evmc_instruction_metrics& a, const evmc_instruction_metrics& b) noexcept
{
return a.gas_cost == b.gas_cost && a.num_stack_arguments == b.num_stack_arguments &&
a.num_stack_returned_items == b.num_stack_returned_items;
}
TEST(instructions, name_gas_cost_equivalence)
{
for (auto r = int{EVMC_FRONTIER}; r <= EVMC_MAX_REVISION; ++r)
{
const auto rev = static_cast<evmc_revision>(r);
const auto names = evmc_get_instruction_names_table(rev);
const auto metrics = evmc_get_instruction_metrics_table(rev);
for (int i = 0; i < 256; ++i)
{
auto name = names[i];
auto gas_cost = metrics[i].gas_cost;
if (name != nullptr)
EXPECT_GE(gas_cost, 0);
else
EXPECT_EQ(gas_cost, -1);
}
}
}
TEST(instructions, homestead_hard_fork) TEST(instructions, homestead_hard_fork)
{ {
const auto f = evmc_get_instruction_metrics_table(EVMC_FRONTIER); const auto f = evmc_get_instruction_metrics_table(EVMC_FRONTIER);
@ -13,6 +40,19 @@ TEST(instructions, homestead_hard_fork)
const auto fn = evmc_get_instruction_names_table(EVMC_FRONTIER); const auto fn = evmc_get_instruction_names_table(EVMC_FRONTIER);
const auto hn = evmc_get_instruction_names_table(EVMC_HOMESTEAD); const auto hn = evmc_get_instruction_names_table(EVMC_HOMESTEAD);
for (int op{OP_STOP}; op <= OP_SELFDESTRUCT; ++op)
{
switch (op) // NOLINT
{
case OP_DELEGATECALL:
continue;
default:
EXPECT_EQ(h[op], f[op]) << op;
EXPECT_STREQ(hn[op], fn[op]) << op;
break;
}
}
EXPECT_EQ(f[OP_DELEGATECALL].gas_cost, -1); EXPECT_EQ(f[OP_DELEGATECALL].gas_cost, -1);
EXPECT_EQ(h[OP_DELEGATECALL].gas_cost, 40); EXPECT_EQ(h[OP_DELEGATECALL].gas_cost, 40);
EXPECT_TRUE(fn[OP_DELEGATECALL] == nullptr); EXPECT_TRUE(fn[OP_DELEGATECALL] == nullptr);
@ -23,6 +63,28 @@ TEST(instructions, tangerine_whistle_hard_fork)
{ {
const auto h = evmc_get_instruction_metrics_table(EVMC_HOMESTEAD); const auto h = evmc_get_instruction_metrics_table(EVMC_HOMESTEAD);
const auto tw = evmc_get_instruction_metrics_table(EVMC_TANGERINE_WHISTLE); const auto tw = evmc_get_instruction_metrics_table(EVMC_TANGERINE_WHISTLE);
const auto hn = evmc_get_instruction_names_table(EVMC_HOMESTEAD);
const auto twn = evmc_get_instruction_names_table(EVMC_TANGERINE_WHISTLE);
for (int op{OP_STOP}; op <= OP_SELFDESTRUCT; ++op)
{
switch (op)
{
case OP_EXTCODESIZE:
case OP_EXTCODECOPY:
case OP_BALANCE:
case OP_SLOAD:
case OP_CALL:
case OP_CALLCODE:
case OP_DELEGATECALL:
case OP_SELFDESTRUCT:
continue;
default:
EXPECT_EQ(tw[op], h[op]) << op;
EXPECT_STREQ(twn[op], hn[op]) << op;
break;
}
}
EXPECT_EQ(h[OP_EXTCODESIZE].gas_cost, 20); EXPECT_EQ(h[OP_EXTCODESIZE].gas_cost, 20);
EXPECT_EQ(tw[OP_EXTCODESIZE].gas_cost, 700); EXPECT_EQ(tw[OP_EXTCODESIZE].gas_cost, 700);
@ -53,6 +115,21 @@ TEST(instructions, spurious_dragon_hard_fork)
{ {
const auto sd = evmc_get_instruction_metrics_table(EVMC_SPURIOUS_DRAGON); const auto sd = evmc_get_instruction_metrics_table(EVMC_SPURIOUS_DRAGON);
const auto tw = evmc_get_instruction_metrics_table(EVMC_TANGERINE_WHISTLE); const auto tw = evmc_get_instruction_metrics_table(EVMC_TANGERINE_WHISTLE);
const auto sdn = evmc_get_instruction_names_table(EVMC_SPURIOUS_DRAGON);
const auto twn = evmc_get_instruction_names_table(EVMC_TANGERINE_WHISTLE);
for (int op{OP_STOP}; op <= OP_SELFDESTRUCT; ++op)
{
switch (op) // NOLINT
{
case OP_EXP:
continue;
default:
EXPECT_EQ(sd[op], tw[op]) << op;
EXPECT_STREQ(sdn[op], twn[op]) << op;
break;
}
}
EXPECT_EQ(sd[OP_EXP].gas_cost, 10); EXPECT_EQ(sd[OP_EXP].gas_cost, 10);
EXPECT_EQ(tw[OP_EXP].gas_cost, 10); EXPECT_EQ(tw[OP_EXP].gas_cost, 10);
@ -65,6 +142,22 @@ TEST(instructions, byzantium_hard_fork)
const auto bn = evmc_get_instruction_names_table(EVMC_BYZANTIUM); const auto bn = evmc_get_instruction_names_table(EVMC_BYZANTIUM);
const auto sdn = evmc_get_instruction_names_table(EVMC_SPURIOUS_DRAGON); const auto sdn = evmc_get_instruction_names_table(EVMC_SPURIOUS_DRAGON);
for (int op{OP_STOP}; op <= OP_SELFDESTRUCT; ++op)
{
switch (op)
{
case OP_REVERT:
case OP_RETURNDATACOPY:
case OP_RETURNDATASIZE:
case OP_STATICCALL:
continue;
default:
EXPECT_EQ(b[op], sd[op]) << op;
EXPECT_STREQ(bn[op], sdn[op]) << op;
break;
}
}
EXPECT_EQ(b[OP_REVERT].gas_cost, 0); EXPECT_EQ(b[OP_REVERT].gas_cost, 0);
EXPECT_EQ(b[OP_REVERT].num_stack_arguments, 2); EXPECT_EQ(b[OP_REVERT].num_stack_arguments, 2);
EXPECT_EQ(b[OP_REVERT].num_stack_returned_items, 0); EXPECT_EQ(b[OP_REVERT].num_stack_returned_items, 0);
@ -95,6 +188,31 @@ TEST(instructions, constantinople_hard_fork)
const auto cn = evmc_get_instruction_names_table(EVMC_CONSTANTINOPLE); const auto cn = evmc_get_instruction_names_table(EVMC_CONSTANTINOPLE);
const auto bn = evmc_get_instruction_names_table(EVMC_BYZANTIUM); const auto bn = evmc_get_instruction_names_table(EVMC_BYZANTIUM);
for (int op{OP_STOP}; op <= OP_SELFDESTRUCT; ++op)
{
switch (op)
{
case OP_CREATE2:
case OP_EXTCODEHASH:
case OP_SHL:
case OP_SHR:
case OP_SAR:
continue;
default:
EXPECT_EQ(c[op], b[op]) << op;
EXPECT_STREQ(cn[op], bn[op]) << op;
break;
}
}
for (auto op : {OP_SHL, OP_SHR, OP_SAR})
{
const auto m = c[op];
EXPECT_EQ(m.gas_cost, 3);
EXPECT_EQ(m.num_stack_arguments, 2);
EXPECT_EQ(m.num_stack_returned_items, 1);
}
EXPECT_EQ(c[OP_CREATE2].gas_cost, 32000); EXPECT_EQ(c[OP_CREATE2].gas_cost, 32000);
EXPECT_EQ(c[OP_CREATE2].num_stack_arguments, 4); EXPECT_EQ(c[OP_CREATE2].num_stack_arguments, 4);
EXPECT_EQ(c[OP_CREATE2].num_stack_returned_items, 1); EXPECT_EQ(c[OP_CREATE2].num_stack_returned_items, 1);
@ -110,24 +228,30 @@ TEST(instructions, constantinople_hard_fork)
EXPECT_TRUE(bn[OP_EXTCODEHASH] == nullptr); EXPECT_TRUE(bn[OP_EXTCODEHASH] == nullptr);
} }
TEST(instructions, petersburg_hard_fork)
TEST(instructions, name_gas_cost_equivalence)
{ {
for (auto r = int{EVMC_FRONTIER}; r <= EVMC_MAX_REVISION; ++r) const auto p = evmc_get_instruction_metrics_table(EVMC_PETERSBURG);
const auto c = evmc_get_instruction_metrics_table(EVMC_CONSTANTINOPLE);
const auto pn = evmc_get_instruction_names_table(EVMC_PETERSBURG);
const auto cn = evmc_get_instruction_names_table(EVMC_CONSTANTINOPLE);
for (int op{OP_STOP}; op <= OP_SELFDESTRUCT; ++op)
{ {
const auto rev = static_cast<evmc_revision>(r); EXPECT_EQ(p[op], c[op]) << op;
const auto names = evmc_get_instruction_names_table(rev); EXPECT_STREQ(pn[op], cn[op]) << op;
const auto metrics = evmc_get_instruction_metrics_table(rev); }
}
for (int i = 0; i < 256; ++i)
{ TEST(instructions, istanbul_hard_fork)
auto name = names[i]; {
auto gas_cost = metrics[i].gas_cost; const auto i = evmc_get_instruction_metrics_table(EVMC_ISTANBUL);
const auto p = evmc_get_instruction_metrics_table(EVMC_PETERSBURG);
if (name != nullptr) const auto in = evmc_get_instruction_names_table(EVMC_ISTANBUL);
EXPECT_GE(gas_cost, 0); const auto pn = evmc_get_instruction_names_table(EVMC_PETERSBURG);
else
EXPECT_EQ(gas_cost, -1); for (int op{OP_STOP}; op <= OP_SELFDESTRUCT; ++op)
} {
EXPECT_EQ(i[op], p[op]) << op;
EXPECT_STREQ(in[op], pn[op]) << op;
} }
} }