use super::*;
macro_rules! op {
($code:expr, $name:expr, $gas:expr) => {
OpcodeSpec {
code: $code,
name: $name,
gas: $gas,
}
};
}
pub static OPCODES: Lazy<HashMap<u8, OpcodeSpec>> = Lazy::new(|| {
let mut m = HashMap::new();
let entries = [
op!(0x00, "PUSHINT8", 1),
op!(0x01, "PUSHINT16", 1),
op!(0x02, "PUSHINT32", 1),
op!(0x03, "PUSHINT64", 1),
op!(0x04, "PUSHINT128", 1),
op!(0x05, "PUSHINT256", 1),
op!(0x08, "PUSHT", 1),
op!(0x09, "PUSHF", 1),
op!(0x0A, "PUSHA", 1),
op!(0x0B, "PUSHNULL", 1),
op!(0x0C, "PUSHDATA1", 2),
op!(0x0D, "PUSHDATA2", 2),
op!(0x0E, "PUSHDATA4", 2),
op!(0x0F, "PUSHM1", 1),
op!(0x10, "PUSH0", 1),
op!(0x11, "PUSH1", 1),
op!(0x12, "PUSH2", 1),
op!(0x13, "PUSH3", 1),
op!(0x14, "PUSH4", 1),
op!(0x15, "PUSH5", 1),
op!(0x16, "PUSH6", 1),
op!(0x17, "PUSH7", 1),
op!(0x18, "PUSH8", 1),
op!(0x19, "PUSH9", 1),
op!(0x1A, "PUSH10", 1),
op!(0x1B, "PUSH11", 1),
op!(0x1C, "PUSH12", 1),
op!(0x1D, "PUSH13", 1),
op!(0x1E, "PUSH14", 1),
op!(0x1F, "PUSH15", 1),
op!(0x20, "PUSH16", 1),
op!(0x21, "NOP", 1),
op!(0x22, "JMP", 2),
op!(0x23, "JMP_L", 2),
op!(0x24, "JMPIF", 2),
op!(0x25, "JMPIF_L", 2),
op!(0x26, "JMPIFNOT", 2),
op!(0x27, "JMPIFNOT_L", 2),
op!(0x28, "JMPEQ", 2),
op!(0x29, "JMPEQ_L", 2),
op!(0x2A, "JMPNE", 2),
op!(0x2B, "JMPNE_L", 2),
op!(0x2C, "JMPGT", 2),
op!(0x2D, "JMPGT_L", 2),
op!(0x2E, "JMPGE", 2),
op!(0x2F, "JMPGE_L", 2),
op!(0x30, "JMPLT", 2),
op!(0x31, "JMPLT_L", 2),
op!(0x32, "JMPLE", 2),
op!(0x33, "JMPLE_L", 2),
op!(0x34, "CALL", 512),
op!(0x35, "CALL_L", 512),
op!(0x36, "CALLA", 512),
op!(0x37, "CALLT", 512),
op!(0x38, "ABORT", 1),
op!(0x39, "ASSERT", 1),
op!(0x3A, "THROW", 1),
op!(0x3B, "TRY", 1),
op!(0x3C, "TRY_L", 1),
op!(0x3D, "ENDTRY", 1),
op!(0x3E, "ENDTRY_L", 1),
op!(0x3F, "ENDFINALLY", 1),
op!(0x40, "RET", 0),
op!(0x41, "SYSCALL", 10),
op!(0x43, "DEPTH", 2),
op!(0x45, "DROP", 2),
op!(0x46, "NIP", 2),
op!(0x48, "XDROP", 2),
op!(0x49, "CLEAR", 2),
op!(0x4A, "DUP", 2),
op!(0x4B, "OVER", 2),
op!(0x4D, "PICK", 2),
op!(0x4E, "TUCK", 2),
op!(0x50, "SWAP", 2),
op!(0x51, "ROT", 2),
op!(0x52, "ROLL", 2),
op!(0x53, "REVERSE3", 2),
op!(0x54, "REVERSE4", 2),
op!(0x55, "REVERSEN", 2),
op!(0x56, "INITSSLOT", 2),
op!(0x57, "INITSLOT", 3),
op!(0x58, "LDSFLD0", 2),
op!(0x59, "LDSFLD1", 2),
op!(0x5A, "LDSFLD2", 2),
op!(0x5B, "LDSFLD3", 2),
op!(0x5C, "LDSFLD4", 2),
op!(0x5D, "LDSFLD5", 2),
op!(0x5E, "LDSFLD6", 2),
op!(0x5F, "LDSFLD", 2),
op!(0x60, "STSFLD0", 2),
op!(0x61, "STSFLD1", 2),
op!(0x62, "STSFLD2", 2),
op!(0x63, "STSFLD3", 2),
op!(0x64, "STSFLD4", 2),
op!(0x65, "STSFLD5", 2),
op!(0x66, "STSFLD6", 2),
op!(0x67, "STSFLD", 2),
op!(0x68, "LDLOC0", 2),
op!(0x69, "LDLOC1", 2),
op!(0x6A, "LDLOC2", 2),
op!(0x6B, "LDLOC3", 2),
op!(0x6C, "LDLOC4", 2),
op!(0x6D, "LDLOC5", 2),
op!(0x6E, "LDLOC6", 2),
op!(0x6F, "LDLOC", 2),
op!(0x70, "STLOC0", 2),
op!(0x71, "STLOC1", 2),
op!(0x72, "STLOC2", 2),
op!(0x73, "STLOC3", 2),
op!(0x74, "STLOC4", 2),
op!(0x75, "STLOC5", 2),
op!(0x76, "STLOC6", 2),
op!(0x77, "STLOC", 2),
op!(0x78, "LDARG0", 2),
op!(0x79, "LDARG1", 2),
op!(0x7A, "LDARG2", 2),
op!(0x7B, "LDARG3", 2),
op!(0x7C, "LDARG4", 2),
op!(0x7D, "LDARG5", 2),
op!(0x7E, "LDARG6", 2),
op!(0x7F, "LDARG", 2),
op!(0x80, "STARG0", 2),
op!(0x81, "STARG1", 2),
op!(0x82, "STARG2", 2),
op!(0x83, "STARG3", 2),
op!(0x84, "STARG4", 2),
op!(0x85, "STARG5", 2),
op!(0x86, "STARG6", 2),
op!(0x87, "STARG", 2),
op!(0x88, "NEWBUFFER", 4),
op!(0x89, "MEMCPY", 4),
op!(0x8B, "CAT", 4),
op!(0x8C, "SUBSTR", 4),
op!(0x8D, "LEFT", 4),
op!(0x8E, "RIGHT", 4),
op!(0x90, "INVERT", 3),
op!(0x91, "AND", 3),
op!(0x92, "OR", 3),
op!(0x93, "XOR", 3),
op!(0x97, "EQUAL", 3),
op!(0x98, "NOTEQUAL", 3),
op!(0x99, "SIGN", 3),
op!(0x9A, "ABS", 3),
op!(0x9B, "NEGATE", 3),
op!(0x9C, "INC", 3),
op!(0x9D, "DEC", 3),
op!(0x9E, "ADD", 3),
op!(0x9F, "SUB", 3),
op!(0xA0, "MUL", 5),
op!(0xA1, "DIV", 5),
op!(0xA2, "MOD", 5),
op!(0xA3, "POW", 8),
op!(0xA4, "SQRT", 6),
op!(0xA5, "MODMUL", 8),
op!(0xA6, "MODPOW", 8),
op!(0xA8, "SHL", 3),
op!(0xA9, "SHR", 3),
op!(0xAA, "NOT", 2),
op!(0xAB, "BOOLAND", 2),
op!(0xAC, "BOOLOR", 2),
op!(0xB1, "NZ", 2),
op!(0xB3, "NUMEQUAL", 3),
op!(0xB4, "NUMNOTEQUAL", 3),
op!(0xB5, "LT", 3),
op!(0xB6, "LE", 3),
op!(0xB7, "GT", 3),
op!(0xB8, "GE", 3),
op!(0xB9, "MIN", 3),
op!(0xBA, "MAX", 3),
op!(0xBB, "WITHIN", 3),
op!(0xBE, "PACKMAP", 4),
op!(0xBF, "PACKSTRUCT", 4),
op!(0xC0, "PACK", 4),
op!(0xC1, "UNPACK", 4),
op!(0xC2, "NEWARRAY0", 4),
op!(0xC3, "NEWARRAY", 4),
op!(0xC4, "NEWARRAY_T", 4),
op!(0xC5, "NEWSTRUCT0", 4),
op!(0xC6, "NEWSTRUCT", 4),
op!(0xC8, "NEWMAP", 4),
op!(0xCA, "SIZE", 4),
op!(0xCB, "HASKEY", 4),
op!(0xCC, "KEYS", 4),
op!(0xCD, "VALUES", 4),
op!(0xCE, "PICKITEM", 4),
op!(0xCF, "APPEND", 4),
op!(0xD0, "SETITEM", 4),
op!(0xD1, "REVERSEITEMS", 4),
op!(0xD2, "REMOVE", 4),
op!(0xD3, "CLEARITEMS", 4),
op!(0xD4, "POPITEM", 4),
op!(0xD8, "ISNULL", 2),
op!(0xD9, "ISTYPE", 2),
op!(0xDB, "CONVERT", 2),
op!(0xE0, "ABORTMSG", 1),
op!(0xE1, "ASSERTMSG", 1),
];
for entry in entries {
m.insert(entry.code, entry);
}
m
});
pub fn opcode_name(code: u8) -> Option<&'static str> {
OPCODES.get(&code).map(|op| op.name)
}
pub fn opcode_gas(code: u8) -> Option<u64> {
OPCODES.get(&code).map(|op| op.gas)
}