Add evmtool pretty-print support for legacy code. (#8398)

* Add pretty-print support for legacy code.

Add support for non-EOF contained code to `evmtool pretty-print`.

Signed-off-by: Danno Ferrin <danno@numisight.com>

* Add junit test

Signed-off-by: Danno Ferrin <danno@numisight.com>

* JUMPDEST hadling

Signed-off-by: Danno Ferrin <danno@numisight.com>

---------

Signed-off-by: Danno Ferrin <danno@numisight.com>
Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
This commit is contained in:
Danno Ferrin
2025-03-12 16:54:42 -06:00
committed by GitHub
parent 2db46e964c
commit 9bd3c166fc
4 changed files with 332 additions and 11 deletions

View File

@@ -18,6 +18,7 @@ import static org.hyperledger.besu.evmtool.PrettyPrintSubCommand.COMMAND_NAME;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.referencetests.ReferenceTestProtocolSchedules;
import org.hyperledger.besu.evm.Code;
import org.hyperledger.besu.evm.EVM;
import org.hyperledger.besu.evm.EvmSpecVersion;
import org.hyperledger.besu.evm.code.CodeInvalid;
@@ -96,17 +97,19 @@ public class PrettyPrintSubCommand implements Runnable {
parentCommand.out.println("Invalid hex string: " + e.getMessage());
continue;
}
if (container.get(0) != ((byte) 0xef) && container.get(1) != 0) {
parentCommand.out.println(
"Pretty printing of legacy EVM is not supported. Patches welcome!");
String fork = EvmSpecVersion.OSAKA.getName();
if (parentCommand.hasFork()) {
fork = parentCommand.getFork();
}
ProtocolSpec protocolSpec = ReferenceTestProtocolSchedules.getInstance().geSpecByName(fork);
EVM evm = protocolSpec.getEvm();
if (evm.getEvmVersion().getMaxEofVersion() < 1
|| container.get(0) != ((byte) 0xef)
|| container.get(1) != 0) {
Code code = evm.getCodeUncached(container);
parentCommand.out.print(code.prettyPrint());
parentCommand.out.flush();
} else {
String fork = EvmSpecVersion.OSAKA.getName();
if (parentCommand.hasFork()) {
fork = parentCommand.getFork();
}
ProtocolSpec protocolSpec = ReferenceTestProtocolSchedules.getInstance().geSpecByName(fork);
EVM evm = protocolSpec.getEvm();
EOFLayout layout = evm.parseEOF(container);
if (layout.isValid()) {
var validatedCode = evm.getCodeUncached(container);

View File

@@ -0,0 +1,8 @@
{
"cli": [
"pretty-print",
"60538060095f395ff33373fffffffffffffffffffffffffffffffffffffffe14604f5760203603604b575f35600143038111604b57611fff81430311604b57611fff9006545f5260205ff35b5f5ffd5b5f35611fff60014303065500"
],
"stdin": "",
"stdout": "0x # Legacy EVM Code\n6053 # [ 0 ] PUSH1(83)\n80 # [ 2 ] DUP1\n6009 # [ 3 ] PUSH1(9)\n5f # [ 5 ] PUSH0\n39 # [ 6 ] CODECOPY\n5f # [ 7 ] PUSH0\nf3 # [ 8 ] RETURN\n33 # [ 9 ] CALLER\n73fffffffffffffffffffffffffffffffffffffffe # [ 10 ] PUSH20\n14 # [ 31 ] EQ\n604f # [ 32 ] PUSH1(79)\n57 # [ 34 ] JUMPI\n6020 # [ 35 ] PUSH1(32)\n36 # [ 37 ] CALLDATASIZE\n03 # [ 38 ] SUB\n604b # [ 39 ] PUSH1(75)\n57 # [ 41 ] JUMPI\n5f # [ 42 ] PUSH0\n35 # [ 43 ] CALLDATALOAD\n6001 # [ 44 ] PUSH1(1)\n43 # [ 46 ] NUMBER\n03 # [ 47 ] SUB\n81 # [ 48 ] DUP2\n11 # [ 49 ] GT\n604b # [ 50 ] PUSH1(75)\n57 # [ 52 ] JUMPI\n611fff # [ 53 ] PUSH2(8191)\n81 # [ 56 ] DUP2\n43 # [ 57 ] NUMBER\n03 # [ 58 ] SUB\n11 # [ 59 ] GT\n604b # [ 60 ] PUSH1(75)\n57 # [ 62 ] JUMPI\n611fff # [ 63 ] PUSH2(8191)\n90 # [ 66 ] SWAP1\n06 # [ 67 ] MOD\n54 # [ 68 ] SLOAD\n5f # [ 69 ] PUSH0\n52 # [ 70 ] MSTORE\n6020 # [ 71 ] PUSH1(32)\n5f # [ 73 ] PUSH0\nf3 # [ 74 ] RETURN\n5b # [ 75 ] JUMPDEST\n5f # [ 76 ] PUSH0\n5f # [ 77 ] PUSH0\nfd # [ 78 ] REVERT\n5b # [ 79 ] JUMPDEST\n5f # [ 80 ] PUSH0\n35 # [ 81 ] CALLDATALOAD\n611fff # [ 82 ] PUSH2(8191)\n6001 # [ 85 ] PUSH1(1)\n43 # [ 87 ] NUMBER\n03 # [ 88 ] SUB\n06 # [ 89 ] MOD\n55 # [ 90 ] SSTORE\n00 # [ 91 ] STOP\n"
}

View File

@@ -20,6 +20,9 @@ import org.hyperledger.besu.evm.EVM;
import org.hyperledger.besu.evm.internal.Words;
import org.hyperledger.besu.evm.operation.JumpDestOperation;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.function.Supplier;
@@ -340,6 +343,43 @@ public class CodeV0 implements Code {
@Override
public String prettyPrint() {
return bytes.toHexString();
int i = 0;
int len = bytes.size();
ByteArrayOutputStream out = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(out);
ps.println("0x # Legacy EVM Code");
while (i < len) {
i += printInstruction(i, ps);
}
return out.toString(StandardCharsets.UTF_8);
}
/**
* Prints an individual instruction, including immediate data
*
* @param offset Offset within the code
* @param out the print stream to write to
* @return the number of bytes to advance the PC (includes consideration of immediate arguments)
*/
public int printInstruction(final int offset, final PrintStream out) {
int codeByte = bytes.get(offset) & 0xff;
OpcodeInfo info = OpcodeInfo.getLegacyOpcode(codeByte);
String push = "";
String decimalPush = "";
if (info.pcAdvance() > 1) {
int start = Math.min(bytes.size(), offset + 1);
int end = Math.min(bytes.size(), info.pcAdvance() - 1);
Bytes slice = bytes.slice(start, end);
push = slice.toUnprefixedHexString();
if (info.pcAdvance() < 5) {
decimalPush = "(" + slice.toLong() + ")";
}
}
String name = info.name();
if (codeByte == 0x5b) {
name = "JUMPDEST";
}
out.printf("%02x%s # [ %d ] %s%s%n", codeByte, push, offset, name, decimalPush);
return Math.max(1, info.pcAdvance());
}
}

View File

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