Opcode metadata registry — single source of truth for every opcode's name, stack I/O signature, implementing module, and static-context flag.
Given an opcode byte (0x00–0xFF) info/1 returns:
:name— the human-readable mnemonic (e.g."ADD"):inputs/:outputs— stack arity, used by the disassembler and stack-depth checks:module— theEEVM.Interpreter.Instructions.*module that implements the opcode;EEVM.Interpreterdispatches on this field:kind— how the interpreter runs it::stackopcodes are pure functions of the stack, implemented asmodule.stack_op(opcode, stack)on a list; this is the default for the Arithmetic, Comparison, Bitwise, and StackOps modules.:controlopcodes (PUSH0–PUSH32, JUMP, JUMPI, JUMPDEST, PC, GAS) read or move the interpreter loop's own registers, soEEVM.Interpreterimplements them.:stateopcodes read or write the machine state throughmodule.execute(opcode, state).
:state_mutating(when present) — opcode mutates persistent state and is an exceptional halt ({:error, :static_state_modification}) inside a STATICCALL frame:eip(when present) — theEEVM.HardforkConfigflag of the EIP that introduced the opcode; before that EIP activates the byte is undefined. Opcodes without it exist since Frontier.EEVM.Interpreter.InstructionTableapplies this per hardfork.
PUSH1–PUSH32, DUP1–DUP16, and SWAP1–SWAP16 are generated dynamically from their opcode ranges rather than stored in the static map.
Summary
Functions
@spec dup?(non_neg_integer()) :: boolean()
@spec info(non_neg_integer()) :: {:ok, map()} | {:error, :unknown_opcode}
@spec push?(non_neg_integer()) :: boolean()
@spec push_bytes(non_neg_integer()) :: non_neg_integer()
@spec swap?(non_neg_integer()) :: boolean()