neo3/neo_types/
op_code.rs

1// op_code
2use getset::Getters;
3use num_enum::TryFromPrimitive;
4use strum_macros::{Display, EnumCount, EnumString};
5
6#[derive(
7	Display, EnumString, EnumCount, TryFromPrimitive, Debug, Copy, Clone, PartialEq, Eq, Hash,
8)]
9#[repr(u8)]
10pub enum OpCode {
11	#[strum(serialize = "PushInt8")]
12	PushInt8 = 0x00,
13	#[strum(serialize = "PushInt16")]
14	PushInt16 = 0x01,
15	#[strum(serialize = "PushInt32")]
16	PushInt32 = 0x02,
17	#[strum(serialize = "PushInt64")]
18	PushInt64 = 0x03,
19	#[strum(serialize = "PushInt128")]
20	PushInt128 = 0x04,
21	#[strum(serialize = "PushInt256")]
22	PushInt256 = 0x05,
23	#[strum(serialize = "PushTrue")]
24	PushTrue = 0x08,
25	#[strum(serialize = "PushFalse")]
26	PushFalse = 0x09,
27	#[strum(serialize = "PushA")]
28	PushA = 0x0A,
29	#[strum(serialize = "PushNull")]
30	PushNull = 0x0B,
31	#[strum(serialize = "PushData1")]
32	PushData1 = 0x0C,
33	#[strum(serialize = "PushData2")]
34	PushData2 = 0x0D,
35	#[strum(serialize = "PushData4")]
36	PushData4 = 0x0E,
37	#[strum(serialize = "PushM1")]
38	PushM1 = 0x0F,
39	#[strum(serialize = "Push0")]
40	Push0 = 0x10,
41	#[strum(serialize = "Push1")]
42	Push1 = 0x11,
43	#[strum(serialize = "Push2")]
44	Push2 = 0x12,
45	#[strum(serialize = "Push3")]
46	Push3 = 0x13,
47	#[strum(serialize = "Push4")]
48	Push4 = 0x14,
49	#[strum(serialize = "Push5")]
50	Push5 = 0x15,
51	#[strum(serialize = "Push6")]
52	Push6 = 0x16,
53	#[strum(serialize = "Push7")]
54	Push7 = 0x17,
55	#[strum(serialize = "Push8")]
56	Push8 = 0x18,
57	#[strum(serialize = "Push9")]
58	Push9 = 0x19,
59	#[strum(serialize = "Push10")]
60	Push10 = 0x1A,
61	#[strum(serialize = "Push11")]
62	Push11 = 0x1B,
63	#[strum(serialize = "Push12")]
64	Push12 = 0x1C,
65	#[strum(serialize = "Push13")]
66	Push13 = 0x1D,
67	#[strum(serialize = "Push14")]
68	Push14 = 0x1E,
69	#[strum(serialize = "Push15")]
70	Push15 = 0x1F,
71	#[strum(serialize = "Push16")]
72	Push16 = 0x20,
73
74	#[strum(serialize = "Nop")]
75	Nop = 0x21,
76	#[strum(serialize = "Jmp")]
77	Jmp = 0x22,
78	#[strum(serialize = "JmpL")]
79	JmpL = 0x23,
80	#[strum(serialize = "JmpIf")]
81	JmpIf = 0x24,
82	#[strum(serialize = "JmpIfL")]
83	JmpIfL = 0x25,
84	#[strum(serialize = "JmpIfNot")]
85	JmpIfNot = 0x26,
86	#[strum(serialize = "JmpIfNotL")]
87	JmpIfNotL = 0x27,
88	#[strum(serialize = "JmpEq")]
89	JmpEq = 0x28,
90	#[strum(serialize = "JmpEqL")]
91	JmpEqL = 0x29,
92	#[strum(serialize = "JmpNe")]
93	JmpNe = 0x2A,
94	#[strum(serialize = "JmpNeL")]
95	JmpNeL = 0x2B,
96	#[strum(serialize = "JmpGt")]
97	JmpGt = 0x2C,
98	#[strum(serialize = "JmpGtL")]
99	JmpGtL = 0x2D,
100	#[strum(serialize = "JmpGe")]
101	JmpGe = 0x2E,
102	#[strum(serialize = "JmpGeL")]
103	JmpGeL = 0x2F,
104	#[strum(serialize = "JmpLt")]
105	JmpLt = 0x30,
106	#[strum(serialize = "JmpLtL")]
107	JmpLtL = 0x31,
108	#[strum(serialize = "JmpLe")]
109	JmpLe = 0x32,
110	#[strum(serialize = "JmpLeL")]
111	JmpLeL = 0x33,
112	#[strum(serialize = "Call")]
113	Call = 0x34,
114	#[strum(serialize = "CallL")]
115	CallL = 0x35,
116	#[strum(serialize = "CallA")]
117	CallA = 0x36,
118	#[strum(serialize = "CallT")]
119	CallT = 0x37,
120	#[strum(serialize = "Abort")]
121	Abort = 0x38,
122	#[strum(serialize = "Assert")]
123	Assert = 0x39,
124	#[strum(serialize = "Throw")]
125	Throw = 0x3A,
126	#[strum(serialize = "Try")]
127	Try = 0x3B,
128	#[strum(serialize = "TryL")]
129	TryL = 0x3C,
130	#[strum(serialize = "EndTry")]
131	EndTry = 0x3D,
132	#[strum(serialize = "EndTryL")]
133	EndTryL = 0x3E,
134	#[strum(serialize = "EndFinally")]
135	EndFinally = 0x3F,
136	#[strum(serialize = "Ret")]
137	Ret = 0x40,
138	#[strum(serialize = "Syscall")]
139	Syscall = 0x41,
140
141	#[strum(serialize = "Depth")]
142	Depth = 0x43,
143	#[strum(serialize = "Drop")]
144	Drop = 0x45,
145	#[strum(serialize = "Nip")]
146	Nip = 0x46,
147	#[strum(serialize = "Xdrop")]
148	Xdrop = 0x48,
149	#[strum(serialize = "Clear")]
150	Clear = 0x49,
151	#[strum(serialize = "Dup")]
152	Dup = 0x4A,
153	#[strum(serialize = "Over")]
154	Over = 0x4B,
155	#[strum(serialize = "Pick")]
156	Pick = 0x4D,
157	#[strum(serialize = "Tuck")]
158	Tuck = 0x4E,
159	#[strum(serialize = "Swap")]
160	Swap = 0x50,
161	#[strum(serialize = "Rot")]
162	Rot = 0x51,
163	#[strum(serialize = "Roll")]
164	Roll = 0x52,
165	#[strum(serialize = "Reverse3")]
166	Reverse3 = 0x53,
167	#[strum(serialize = "Reverse4")]
168	Reverse4 = 0x54,
169	#[strum(serialize = "Reverse5")]
170	ReverseN = 0x55,
171
172	#[strum(serialize = "InitSSlot")]
173	InitSSLot = 0x56,
174	#[strum(serialize = "InitSlot")]
175	InitSlot = 0x57,
176
177	#[strum(serialize = "LdSFLd0")]
178	LdSFLd0 = 0x58,
179	#[strum(serialize = "LdSFLd1")]
180	LdSFLd1 = 0x59,
181	#[strum(serialize = "LdSFLd2")]
182	LdSFLd2 = 0x5A,
183	#[strum(serialize = "LdSFLd3")]
184	LdSFLd3 = 0x5B,
185	#[strum(serialize = "LdSFLd4")]
186	LdSFLd4 = 0x5C,
187	#[strum(serialize = "LdSFLd5")]
188	LdSFLd5 = 0x5D,
189	#[strum(serialize = "LdSFLd6")]
190	LdSFLd6 = 0x5E,
191	#[strum(serialize = "LdSFLd")]
192	LdSFLd = 0x5F,
193
194	#[strum(serialize = "StSFLd0")]
195	StSFLd0 = 0x60,
196	#[strum(serialize = "StSFLd1")]
197	StSFLd1 = 0x61,
198	#[strum(serialize = "StSFLd2")]
199	StSFLd2 = 0x62,
200	#[strum(serialize = "StSFLd3")]
201	StSFLd3 = 0x63,
202	#[strum(serialize = "StSFLd4")]
203	StSFLd4 = 0x64,
204	#[strum(serialize = "StSFLd5")]
205	StSFLd5 = 0x65,
206	#[strum(serialize = "StSFLd6")]
207	StSFLd6 = 0x66,
208	#[strum(serialize = "StSFLd")]
209	StSFLd = 0x67,
210
211	#[strum(serialize = "LdLoc0")]
212	LdLoc0 = 0x68,
213	#[strum(serialize = "LdLoc1")]
214	LdLoc1 = 0x69,
215	#[strum(serialize = "LdLoc2")]
216	LdLoc2 = 0x6A,
217	#[strum(serialize = "LdLoc3")]
218	LdLoc3 = 0x6B,
219	#[strum(serialize = "LdLoc4")]
220	LdLoc4 = 0x6C,
221	#[strum(serialize = "LdLoc5")]
222	LdLoc5 = 0x6D,
223	#[strum(serialize = "LdLoc6")]
224	LdLoc6 = 0x6E,
225	#[strum(serialize = "LdLoc")]
226	LdLoc = 0x6F,
227
228	#[strum(serialize = "StLoc0")]
229	StLoc0 = 0x70,
230	#[strum(serialize = "StLoc1")]
231	StLoc1 = 0x71,
232	#[strum(serialize = "StLoc2")]
233	StLoc2 = 0x72,
234	#[strum(serialize = "StLoc3")]
235	StLoc3 = 0x73,
236	#[strum(serialize = "StLoc4")]
237	StLoc4 = 0x74,
238	#[strum(serialize = "StLoc5")]
239	StLoc5 = 0x75,
240	#[strum(serialize = "StLoc6")]
241	StLoc6 = 0x76,
242	#[strum(serialize = "StLoc")]
243	StLoc = 0x77,
244
245	#[strum(serialize = "LdArg0")]
246	LdArg0 = 0x78,
247	#[strum(serialize = "LdArg1")]
248	LdArg1 = 0x79,
249	#[strum(serialize = "LdArg2")]
250	LdArg2 = 0x7A,
251	#[strum(serialize = "LdArg3")]
252	LdArg3 = 0x7B,
253	#[strum(serialize = "LdArg4")]
254	LdArg4 = 0x7C,
255	#[strum(serialize = "LdArg5")]
256	LdArg5 = 0x7D,
257	#[strum(serialize = "LdArg6")]
258	LdArg6 = 0x7E,
259	#[strum(serialize = "LdArg")]
260	LdArg = 0x7F,
261
262	#[strum(serialize = "StArg0")]
263	StArg0 = 0x80,
264	#[strum(serialize = "StArg1")]
265	StArg1 = 0x81,
266	#[strum(serialize = "StArg2")]
267	StArg2 = 0x82,
268	#[strum(serialize = "StArg3")]
269	StArg3 = 0x83,
270	#[strum(serialize = "StArg4")]
271	StArg4 = 0x84,
272	#[strum(serialize = "StArg5")]
273	StArg5 = 0x85,
274	#[strum(serialize = "StArg6")]
275	StArg6 = 0x86,
276	#[strum(serialize = "StArg")]
277	StArg = 0x87,
278
279	#[strum(serialize = "NewBuffer")]
280	NewBuffer = 0x88,
281	#[strum(serialize = "MemCpy")]
282	MemCpy = 0x89,
283	#[strum(serialize = "Cat")]
284	Cat = 0x8B,
285	#[strum(serialize = "Substr")]
286	Substr = 0x8C,
287	#[strum(serialize = "Left")]
288	Left = 0x8D,
289	#[strum(serialize = "Right")]
290	Right = 0x8E,
291
292	#[strum(serialize = "Invert")]
293	Invert = 0x90,
294	#[strum(serialize = "And")]
295	And = 0x91,
296	#[strum(serialize = "Or")]
297	Or = 0x92,
298	#[strum(serialize = "Xor")]
299	Xor = 0x93,
300	#[strum(serialize = "Equal")]
301	Equal = 0x97,
302	#[strum(serialize = "NotEqual")]
303	NotEqual = 0x98,
304
305	#[strum(serialize = "Sign")]
306	Sign = 0x99,
307	#[strum(serialize = "Abs")]
308	Abs = 0x9A,
309	#[strum(serialize = "Negate")]
310	Negate = 0x9B,
311	#[strum(serialize = "Inc")]
312	Inc = 0x9C,
313	#[strum(serialize = "Dec")]
314	Dec = 0x9D,
315	#[strum(serialize = "Add")]
316	Add = 0x9E,
317	#[strum(serialize = "Sub")]
318	Sub = 0x9F,
319	#[strum(serialize = "Mul")]
320	Mul = 0xA0,
321	#[strum(serialize = "Div")]
322	Div = 0xA1,
323	#[strum(serialize = "Mod")]
324	Mod = 0xA2,
325	#[strum(serialize = "Pow")]
326	Pow = 0xA3,
327	#[strum(serialize = "Sqrt")]
328	Sqrt = 0xA4,
329	#[strum(serialize = "ModMul")]
330	ModMul = 0xA5,
331	#[strum(serialize = "ModPow")]
332	ModPow = 0xA6,
333	#[strum(serialize = "Shl")]
334	Shl = 0xA8,
335	#[strum(serialize = "Shr")]
336	Shr = 0xA9,
337	#[strum(serialize = "Not")]
338	Not = 0xAA,
339	#[strum(serialize = "BoolAnd")]
340	BoolAnd = 0xAB,
341	#[strum(serialize = "BoolOr")]
342	BoolOr = 0xAC,
343	#[strum(serialize = "Nz")]
344	Nz = 0xB1,
345	#[strum(serialize = "NumEqual")]
346	NumEqual = 0xB3,
347	#[strum(serialize = "NumNotEqual")]
348	NumNotEqual = 0xB4,
349	#[strum(serialize = "Lt")]
350	Lt = 0xB5,
351	#[strum(serialize = "Le")]
352	Le = 0xB6,
353	#[strum(serialize = "Gt")]
354	Gt = 0xB7,
355	#[strum(serialize = "Ge")]
356	Ge = 0xB8,
357	#[strum(serialize = "Min")]
358	Min = 0xB9,
359	#[strum(serialize = "Max")]
360	Max = 0xBA,
361	#[strum(serialize = "Within")]
362	Within = 0xBB,
363
364	#[strum(serialize = "PackMap")]
365	PackMap = 0xBE,
366	#[strum(serialize = "PackStruct")]
367	PackStruct = 0xBF,
368	#[strum(serialize = "Pack")]
369	Pack = 0xC0,
370	#[strum(serialize = "Unpack")]
371	Unpack = 0xC1,
372	#[strum(serialize = "NewArray0")]
373	NewArray0 = 0xC2,
374	#[strum(serialize = "NewArray")]
375	NewArray = 0xC3,
376	#[strum(serialize = "NewArrayT")]
377	NewArrayT = 0xC4,
378	#[strum(serialize = "NewStruct0")]
379	NewStruct0 = 0xC5,
380	#[strum(serialize = "NewStruct")]
381	NewStruct = 0xC6,
382	#[strum(serialize = "NewMap")]
383	NewMap = 0xC8,
384	#[strum(serialize = "Size")]
385	Size = 0xCA,
386	#[strum(serialize = "HasKey")]
387	HasKey = 0xCB,
388	#[strum(serialize = "Keys")]
389	Keys = 0xCC,
390	#[strum(serialize = "Values")]
391	Values = 0xCD,
392	#[strum(serialize = "PickItem")]
393	PickItem = 0xCE,
394	#[strum(serialize = "Append")]
395	Append = 0xCF,
396	#[strum(serialize = "SetItem")]
397	SetItem = 0xD0,
398	#[strum(serialize = "ReverseItems")]
399	ReverseItems = 0xD1,
400	#[strum(serialize = "Remove")]
401	Remove = 0xD2,
402	#[strum(serialize = "ClearItems")]
403	ClearItems = 0xD3,
404	#[strum(serialize = "PopItem")]
405	PopItem = 0xD4,
406
407	#[strum(serialize = "IsNull")]
408	IsNull = 0xD8,
409	#[strum(serialize = "IsType")]
410	IsType = 0xD9,
411	#[strum(serialize = "Convert")]
412	Convert = 0xDB,
413
414	#[strum(serialize = "AbortMsg")]
415	AbortMsg = 0xE0,
416	#[strum(serialize = "AssertMsg")]
417	AssertMsg = 0xE1,
418}
419
420impl OpCode {
421	pub fn price(self) -> u32 {
422		match self {
423			OpCode::PushInt8
424			| OpCode::PushInt16
425			| OpCode::PushInt32
426			| OpCode::PushInt64
427			| OpCode::PushNull
428			| OpCode::PushM1
429			| OpCode::Push0
430			| OpCode::Push1
431			| OpCode::Push2
432			| OpCode::Push3
433			| OpCode::Push4
434			| OpCode::Push5
435			| OpCode::Push6
436			| OpCode::Push7
437			| OpCode::Push8
438			| OpCode::Push9
439			| OpCode::Push10
440			| OpCode::Push11
441			| OpCode::Push12
442			| OpCode::Push13
443			| OpCode::Push14
444			| OpCode::Push15
445			| OpCode::Push16
446			| OpCode::Nop
447			| OpCode::Assert => 1,
448			OpCode::PushInt128
449			| OpCode::PushInt256
450			| OpCode::PushA
451			| OpCode::Try
452			| OpCode::Sign
453			| OpCode::Abs
454			| OpCode::Negate
455			| OpCode::Inc
456			| OpCode::Dec
457			| OpCode::Not
458			| OpCode::Nz
459			| OpCode::Size => 1 << 2,
460			OpCode::PushData1
461			| OpCode::And
462			| OpCode::Or
463			| OpCode::Xor
464			| OpCode::Add
465			| OpCode::Sub
466			| OpCode::Mul
467			| OpCode::Div
468			| OpCode::Mod
469			| OpCode::Shl
470			| OpCode::Shr
471			| OpCode::BoolAnd
472			| OpCode::BoolOr
473			| OpCode::NumEqual
474			| OpCode::NumNotEqual
475			| OpCode::Lt
476			| OpCode::Le
477			| OpCode::Gt
478			| OpCode::Ge
479			| OpCode::Min
480			| OpCode::Max
481			| OpCode::Within
482			| OpCode::NewMap => 1 << 3,
483			OpCode::Xdrop
484			| OpCode::Clear
485			| OpCode::Roll
486			| OpCode::ReverseN
487			| OpCode::InitSSLot
488			| OpCode::NewArray0
489			| OpCode::NewStruct0
490			| OpCode::Keys
491			| OpCode::Remove
492			| OpCode::ClearItems => 1 << 4,
493			OpCode::Equal | OpCode::NotEqual | OpCode::ModMul => 1 << 5,
494			OpCode::InitSlot | OpCode::Pow | OpCode::HasKey | OpCode::PickItem => 1 << 6,
495			OpCode::NewBuffer => 1 << 8,
496			OpCode::PushData2
497			| OpCode::Call
498			| OpCode::CallL
499			| OpCode::CallA
500			| OpCode::Throw
501			| OpCode::NewArray
502			| OpCode::NewArrayT
503			| OpCode::NewStruct => 1 << 9,
504			OpCode::MemCpy
505			| OpCode::Cat
506			| OpCode::Substr
507			| OpCode::Left
508			| OpCode::Right
509			| OpCode::Sqrt
510			| OpCode::ModPow
511			| OpCode::PackMap
512			| OpCode::PackStruct
513			| OpCode::Pack
514			| OpCode::Unpack => 1 << 11,
515			OpCode::PushData4 => 1 << 12,
516			OpCode::Values
517			| OpCode::Append
518			| OpCode::SetItem
519			| OpCode::ReverseItems
520			| OpCode::Convert => 1 << 13,
521			OpCode::CallT => 1 << 15,
522			OpCode::Abort | OpCode::Ret | OpCode::Syscall => 0,
523			_ => 1 << 1,
524		}
525	}
526	pub fn opcode(self) -> u8 {
527		self as u8
528	}
529
530	pub fn to_hex_string(self) -> String {
531		format!("{:02X}", self as u8)
532	}
533
534	pub fn operand_size(self) -> Option<OperandSize> {
535		match self {
536			Self::PushInt8
537			| Self::Jmp
538			| Self::JmpIf
539			| Self::JmpIfNot
540			| Self::JmpEq
541			| Self::JmpNe
542			| Self::JmpGt
543			| Self::JmpGe
544			| Self::JmpLt
545			| Self::JmpLe
546			| Self::Call
547			| Self::EndTry
548			| Self::InitSSLot
549			| Self::LdSFLd
550			| Self::StSFLd
551			| Self::LdLoc
552			| Self::StLoc
553			| Self::LdArg
554			| Self::StArg
555			| Self::NewArrayT
556			| Self::IsType
557			| Self::Convert => Some(OperandSize::with_size(1)),
558
559			Self::PushInt16 | Self::CallT | Self::Try | Self::InitSlot =>
560				Some(OperandSize::with_size(2)),
561
562			Self::PushInt32
563			| Self::PushA
564			| Self::JmpL
565			| Self::JmpIfL
566			| Self::JmpIfNotL
567			| Self::JmpEqL
568			| Self::JmpNeL
569			| Self::JmpGtL
570			| Self::JmpGeL
571			| Self::JmpLtL
572			| Self::JmpLeL
573			| Self::CallL
574			| Self::EndTryL
575			| Self::Syscall => Some(OperandSize::with_size(4)),
576
577			Self::PushInt64 | Self::TryL => Some(OperandSize::with_size(8)),
578
579			Self::PushInt128 => Some(OperandSize::with_size(16)),
580
581			Self::PushInt256 => Some(OperandSize::with_size(32)),
582
583			Self::PushData1 => Some(OperandSize::with_prefix_size(1)),
584			Self::PushData2 => Some(OperandSize::with_prefix_size(2)),
585			Self::PushData4 => Some(OperandSize::with_prefix_size(4)),
586
587			_ => None,
588		}
589	}
590}
591
592// impl TryFrom<u8> for OpCode {
593// 	type Error = ();
594//
595// 	fn try_from(value: u8) -> Result<Self, Self::Error> {
596// 		match value {
597// 			0x00 => Ok(OpCode::PushInt8),
598// 			_ => Err(()),
599// 		}
600// 	}
601// }
602
603#[derive(Clone, Debug, Getters)]
604pub struct OperandSize {
605	#[get = "pub"]
606	prefix_size: u8,
607	#[get = "pub"]
608	size: u8,
609}
610
611impl OperandSize {
612	pub fn with_size(size: u8) -> Self {
613		Self { prefix_size: 0, size }
614	}
615
616	pub fn with_prefix_size(prefix_size: u8) -> Self {
617		Self { prefix_size, size: 0 }
618	}
619}