1
2pub enum Opcode {
3 Nop = 0,
4 InitStack = 1,
5 Call = 2,
6 Syscall,
7 Ret,
8 RetV,
9 Jmp,
10 Jz,
11 PushNil,
12 PushTrue,
13 PushI32,
14 PushI16,
15 PushI8,
16 PushF32,
17 PushString,
18 PushGlobal,
19 PushStack,
20 PushGlobalTable,
21 PushLocalTable,
22 PushTop,
23 PushReturn,
24 PopGlobal,
25 PopStack,
26 PopGlobalTable,
27 PopLocalTable,
28 Neg,
29 Add,
30 Sub,
31 Mul,
32 Div,
33 Mod,
34 BitTest,
35 And,
36 Or,
37 SetE,
38 SetNE,
39 SetG,
40 SetLE,
41 SetL,
42 SetGE,
43}
44
45impl TryFrom<i32> for Opcode {
46 type Error = ();
47
48 fn try_from(v: i32) -> core::result::Result<Self, Self::Error> {
49 match v {
50 x if x == Opcode::Nop as i32 => Ok(Opcode::Nop),
51 x if x == Opcode::InitStack as i32 => Ok(Opcode::InitStack),
52 x if x == Opcode::Call as i32 => Ok(Opcode::Call),
53 x if x == Opcode::Syscall as i32 => Ok(Opcode::Syscall),
54 x if x == Opcode::Ret as i32 => Ok(Opcode::Ret),
55 x if x == Opcode::RetV as i32 => Ok(Opcode::RetV),
56 x if x == Opcode::Jmp as i32 => Ok(Opcode::Jmp),
57 x if x == Opcode::Jz as i32 => Ok(Opcode::Jz),
58 x if x == Opcode::PushNil as i32 => Ok(Opcode::PushNil),
59 x if x == Opcode::PushTrue as i32 => Ok(Opcode::PushTrue),
60 x if x == Opcode::PushI32 as i32 => Ok(Opcode::PushI32),
61 x if x == Opcode::PushI16 as i32 => Ok(Opcode::PushI16),
62 x if x == Opcode::PushI8 as i32 => Ok(Opcode::PushI8),
63 x if x == Opcode::PushF32 as i32 => Ok(Opcode::PushF32),
64 x if x == Opcode::PushString as i32 => Ok(Opcode::PushString),
65 x if x == Opcode::PushGlobal as i32 => Ok(Opcode::PushGlobal),
66 x if x == Opcode::PushStack as i32 => Ok(Opcode::PushStack),
67 x if x == Opcode::PushGlobalTable as i32 => Ok(Opcode::PushGlobalTable),
68 x if x == Opcode::PushLocalTable as i32 => Ok(Opcode::PushLocalTable),
69 x if x == Opcode::PushTop as i32 => Ok(Opcode::PushTop),
70 x if x == Opcode::PushReturn as i32 => Ok(Opcode::PushReturn),
71 x if x == Opcode::PopGlobal as i32 => Ok(Opcode::PopGlobal),
72 x if x == Opcode::PopStack as i32 => Ok(Opcode::PopStack),
73 x if x == Opcode::PopGlobalTable as i32 => Ok(Opcode::PopGlobalTable),
74 x if x == Opcode::PopLocalTable as i32 => Ok(Opcode::PopLocalTable),
75 x if x == Opcode::Neg as i32 => Ok(Opcode::Neg),
76 x if x == Opcode::Add as i32 => Ok(Opcode::Add),
77 x if x == Opcode::Sub as i32 => Ok(Opcode::Sub),
78 x if x == Opcode::Mul as i32 => Ok(Opcode::Mul),
79 x if x == Opcode::Div as i32 => Ok(Opcode::Div),
80 x if x == Opcode::Mod as i32 => Ok(Opcode::Mod),
81 x if x == Opcode::BitTest as i32 => Ok(Opcode::BitTest),
82 x if x == Opcode::And as i32 => Ok(Opcode::And),
83 x if x == Opcode::Or as i32 => Ok(Opcode::Or),
84 x if x == Opcode::SetE as i32 => Ok(Opcode::SetE),
85 x if x == Opcode::SetNE as i32 => Ok(Opcode::SetNE),
86 x if x == Opcode::SetG as i32 => Ok(Opcode::SetG),
87 x if x == Opcode::SetLE as i32 => Ok(Opcode::SetLE),
88 x if x == Opcode::SetL as i32 => Ok(Opcode::SetL),
89 x if x == Opcode::SetGE as i32 => Ok(Opcode::SetGE),
90 _ => Err(()),
91 }
92 }
93}
94
95
96impl TryFrom<u8> for Opcode {
97 type Error = ();
98
99 fn try_from(v: u8) -> core::result::Result<Self, Self::Error> {
100 match v {
101 x if x == Opcode::Nop as u8 => Ok(Opcode::Nop),
102 x if x == Opcode::InitStack as u8 => Ok(Opcode::InitStack),
103 x if x == Opcode::Call as u8 => Ok(Opcode::Call),
104 x if x == Opcode::Syscall as u8 => Ok(Opcode::Syscall),
105 x if x == Opcode::Ret as u8 => Ok(Opcode::Ret),
106 x if x == Opcode::RetV as u8 => Ok(Opcode::RetV),
107 x if x == Opcode::Jmp as u8 => Ok(Opcode::Jmp),
108 x if x == Opcode::Jz as u8 => Ok(Opcode::Jz),
109 x if x == Opcode::PushNil as u8 => Ok(Opcode::PushNil),
110 x if x == Opcode::PushTrue as u8 => Ok(Opcode::PushTrue),
111 x if x == Opcode::PushI32 as u8 => Ok(Opcode::PushI32),
112 x if x == Opcode::PushI16 as u8 => Ok(Opcode::PushI16),
113 x if x == Opcode::PushI8 as u8 => Ok(Opcode::PushI8),
114 x if x == Opcode::PushF32 as u8 => Ok(Opcode::PushF32),
115 x if x == Opcode::PushString as u8 => Ok(Opcode::PushString),
116 x if x == Opcode::PushGlobal as u8 => Ok(Opcode::PushGlobal),
117 x if x == Opcode::PushStack as u8 => Ok(Opcode::PushStack),
118 x if x == Opcode::PushGlobalTable as u8 => Ok(Opcode::PushGlobalTable),
119 x if x == Opcode::PushLocalTable as u8 => Ok(Opcode::PushLocalTable),
120 x if x == Opcode::PushTop as u8 => Ok(Opcode::PushTop),
121 x if x == Opcode::PushReturn as u8 => Ok(Opcode::PushReturn),
122 x if x == Opcode::PopGlobal as u8 => Ok(Opcode::PopGlobal),
123 x if x == Opcode::PopStack as u8 => Ok(Opcode::PopStack),
124 x if x == Opcode::PopGlobalTable as u8 => Ok(Opcode::PopGlobalTable),
125 x if x == Opcode::PopLocalTable as u8 => Ok(Opcode::PopLocalTable),
126 x if x == Opcode::Neg as u8 => Ok(Opcode::Neg),
127 x if x == Opcode::Add as u8 => Ok(Opcode::Add),
128 x if x == Opcode::Sub as u8 => Ok(Opcode::Sub),
129 x if x == Opcode::Mul as u8 => Ok(Opcode::Mul),
130 x if x == Opcode::Div as u8 => Ok(Opcode::Div),
131 x if x == Opcode::Mod as u8 => Ok(Opcode::Mod),
132 x if x == Opcode::BitTest as u8 => Ok(Opcode::BitTest),
133 x if x == Opcode::And as u8 => Ok(Opcode::And),
134 x if x == Opcode::Or as u8 => Ok(Opcode::Or),
135 x if x == Opcode::SetE as u8 => Ok(Opcode::SetE),
136 x if x == Opcode::SetNE as u8 => Ok(Opcode::SetNE),
137 x if x == Opcode::SetG as u8 => Ok(Opcode::SetG),
138 x if x == Opcode::SetLE as u8 => Ok(Opcode::SetLE),
139 x if x == Opcode::SetL as u8 => Ok(Opcode::SetL),
140 x if x == Opcode::SetGE as u8 => Ok(Opcode::SetGE),
141 _ => Err(()),
142 }
143 }
144}
145
146impl TryFrom<&str> for Opcode {
147 type Error = ();
148
149 fn try_from(v: &str) -> core::result::Result<Self, Self::Error> {
150 match v {
151 x if x == "nop" => Ok(Opcode::Nop),
152 x if x == "init_stack" => Ok(Opcode::InitStack),
153 x if x == "call" => Ok(Opcode::Call),
154 x if x == "syscall" => Ok(Opcode::Syscall),
155 x if x == "ret" => Ok(Opcode::Ret),
156 x if x == "retv" => Ok(Opcode::RetV),
157 x if x == "jmp" => Ok(Opcode::Jmp),
158 x if x == "jz" => Ok(Opcode::Jz),
159 x if x == "push_nil" => Ok(Opcode::PushNil),
160 x if x == "push_true" => Ok(Opcode::PushTrue),
161 x if x == "push_i32" => Ok(Opcode::PushI32),
162 x if x == "push_i16" => Ok(Opcode::PushI16),
163 x if x == "push_i8" => Ok(Opcode::PushI8),
164 x if x == "push_f32" => Ok(Opcode::PushF32),
165 x if x == "push_string" => Ok(Opcode::PushString),
166 x if x == "push_global" => Ok(Opcode::PushGlobal),
167 x if x == "push_stack" => Ok(Opcode::PushStack),
168 x if x == "push_global_table" => Ok(Opcode::PushGlobalTable),
169 x if x == "push_local_table" => Ok(Opcode::PushLocalTable),
170 x if x == "push_top" => Ok(Opcode::PushTop),
171 x if x == "push_return" => Ok(Opcode::PushReturn),
172 x if x == "pop_global" => Ok(Opcode::PopGlobal),
173 x if x == "pop_stack" => Ok(Opcode::PopStack),
174 x if x == "pop_global_table" => Ok(Opcode::PopGlobalTable),
175 x if x == "pop_local_table" => Ok(Opcode::PopLocalTable),
176 x if x == "neg" => Ok(Opcode::Neg),
177 x if x == "add" => Ok(Opcode::Add),
178 x if x == "sub" => Ok(Opcode::Sub),
179 x if x == "mul" => Ok(Opcode::Mul),
180 x if x == "div" => Ok(Opcode::Div),
181 x if x == "mod" => Ok(Opcode::Mod),
182 x if x == "bit_test" => Ok(Opcode::BitTest),
183 x if x == "and" => Ok(Opcode::And),
184 x if x == "or" => Ok(Opcode::Or),
185 x if x == "set_e" => Ok(Opcode::SetE),
186 x if x == "set_ne" => Ok(Opcode::SetNE),
187 x if x == "set_g" => Ok(Opcode::SetG),
188 x if x == "set_le" => Ok(Opcode::SetLE),
189 x if x == "set_l" => Ok(Opcode::SetL),
190 x if x == "set_ge" => Ok(Opcode::SetGE),
191 _ => Err(()),
192 }
193 }
194}
195
196impl ToString for Opcode {
197 fn to_string(&self) -> String {
198 match self {
199 Opcode::Nop => "nop",
200 Opcode::InitStack => "init_stack",
201 Opcode::Call => "call",
202 Opcode::Syscall => "syscall",
203 Opcode::Ret => "ret",
204 Opcode::RetV => "retv",
205 Opcode::Jmp => "jmp",
206 Opcode::Jz => "jz",
207 Opcode::PushNil => "push_nil",
208 Opcode::PushTrue => "push_true",
209 Opcode::PushI32 => "push_i32",
210 Opcode::PushI16 => "push_i16",
211 Opcode::PushI8 => "push_i8",
212 Opcode::PushF32 => "push_f32",
213 Opcode::PushString => "push_string",
214 Opcode::PushGlobal => "push_global",
215 Opcode::PushStack => "push_stack",
216 Opcode::PushGlobalTable => "push_global_table",
217 Opcode::PushLocalTable => "push_local_table",
218 Opcode::PushTop => "push_top",
219 Opcode::PushReturn => "push_return",
220 Opcode::PopGlobal => "pop_global",
221 Opcode::PopStack => "pop_stack",
222 Opcode::PopGlobalTable => "pop_global_table",
223 Opcode::PopLocalTable => "pop_local_table",
224 Opcode::Neg => "neg",
225 Opcode::Add => "add",
226 Opcode::Sub => "sub",
227 Opcode::Mul => "mul",
228 Opcode::Div => "div",
229 Opcode::Mod => "mod",
230 Opcode::BitTest => "bit_test",
231 Opcode::And => "and",
232 Opcode::Or => "or",
233 Opcode::SetE => "set_e",
234 Opcode::SetNE => "set_ne",
235 Opcode::SetG => "set_g",
236 Opcode::SetLE => "set_le",
237 Opcode::SetL => "set_l",
238 Opcode::SetGE => "set_ge",
239 }.to_string()
240 }
241}
242
243pub trait OpcodeBase {
244 fn opcode(&self) -> Opcode;
245 fn address(&self) -> u32;
246 fn mnemonic(&self) -> &'static str;
247 fn disassemble(&self) -> String;
248}
249