1use super::types::ClrTypeReference;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub enum ClrOpcode {
6 Nop,
8 LdcI4M1,
10 LdcI40,
12 LdcI41,
14 LdcI42,
16 LdcI43,
18 LdcI44,
20 LdcI45,
22 LdcI46,
24 LdcI47,
26 LdcI48,
28 LdcI4S,
30 LdcI4,
32 LdcI8,
34 LdcR4,
36 LdcR8,
38 Ldnull,
40 Ldstr,
42 Ldarg0,
44 Ldarg1,
46 Ldarg2,
48 Ldarg3,
50 Ldloc0,
52 Ldloc1,
54 Ldloc2,
56 Ldloc3,
58 Stloc0,
60 Stloc1,
62 Stloc2,
64 Stloc3,
66 Call,
68 Callvirt,
70 Ret,
72 Newobj,
74 Pop,
76 Dup,
78 Add,
80 Sub,
82 Mul,
84 Div,
86 Ceq,
88 Cgt,
90 Clt,
92 And,
94 Or,
96 Br,
98 Brtrue,
100 Brfalse,
102 Ldloc,
104 Stloc,
106 Ldarg,
108 Starg,
110 Ldloca,
112 Ldfld,
114 Stfld,
116 Ldelem,
118 Stelem,
120 Ldlen,
122 Newarr,
124 Box,
126 Unbox,
128 ConvI4,
130 ConvI8,
132 ConvR4,
134 ConvR8,
136 LdindI4,
138 LdindI8,
140 LdindR4,
142 LdindR8,
144 LdindRef,
146 StindI4,
148 StindI8,
150 StindR4,
152 StindR8,
154 StindRef,
156 Throw,
158}
159
160impl ClrOpcode {
161 pub fn to_byte(&self) -> u8 {
163 match self {
164 ClrOpcode::Nop => 0x00,
165 ClrOpcode::LdcI4M1 => 0x15,
166 ClrOpcode::LdcI40 => 0x16,
167 ClrOpcode::LdcI41 => 0x17,
168 ClrOpcode::LdcI42 => 0x18,
169 ClrOpcode::LdcI43 => 0x19,
170 ClrOpcode::LdcI44 => 0x1A,
171 ClrOpcode::LdcI45 => 0x1B,
172 ClrOpcode::LdcI46 => 0x1C,
173 ClrOpcode::LdcI47 => 0x1D,
174 ClrOpcode::LdcI48 => 0x1E,
175 ClrOpcode::LdcI4S => 0x1F,
176 ClrOpcode::LdcI4 => 0x20,
177 ClrOpcode::LdcI8 => 0x21,
178 ClrOpcode::LdcR4 => 0x22,
179 ClrOpcode::LdcR8 => 0x23,
180 ClrOpcode::Ldnull => 0x14,
181 ClrOpcode::Ldstr => 0x72,
182 ClrOpcode::Ldarg0 => 0x02,
183 ClrOpcode::Ldarg1 => 0x03,
184 ClrOpcode::Ldarg2 => 0x04,
185 ClrOpcode::Ldarg3 => 0x05,
186 ClrOpcode::Ldloc0 => 0x06,
187 ClrOpcode::Ldloc1 => 0x07,
188 ClrOpcode::Ldloc2 => 0x08,
189 ClrOpcode::Ldloc3 => 0x09,
190 ClrOpcode::Stloc0 => 0x0A,
191 ClrOpcode::Stloc1 => 0x0B,
192 ClrOpcode::Stloc2 => 0x0C,
193 ClrOpcode::Stloc3 => 0x0D,
194 ClrOpcode::Call => 0x28,
195 ClrOpcode::Callvirt => 0x6F,
196 ClrOpcode::Ret => 0x2A,
197 ClrOpcode::Newobj => 0x73,
198 ClrOpcode::Pop => 0x25,
199 ClrOpcode::Dup => 0x25,
200 ClrOpcode::Add => 0x58,
201 ClrOpcode::Sub => 0x59,
202 ClrOpcode::Mul => 0x5A,
203 ClrOpcode::Div => 0x5B,
204 ClrOpcode::Ceq => 0xFE, ClrOpcode::Cgt => 0xFE, ClrOpcode::Clt => 0xFE, ClrOpcode::And => 0x5F,
208 ClrOpcode::Or => 0x60,
209 ClrOpcode::Br => 0x38,
210 ClrOpcode::Brtrue => 0x3A,
211 ClrOpcode::Brfalse => 0x3B,
212 ClrOpcode::Ldloc => 0xFE, ClrOpcode::Stloc => 0xFE, ClrOpcode::Ldarg => 0xFE, ClrOpcode::Starg => 0xFE, ClrOpcode::Ldloca => 0xFE, ClrOpcode::Ldfld => 0x7B,
218 ClrOpcode::Stfld => 0x7C,
219 ClrOpcode::Ldelem => 0xA3,
220 ClrOpcode::Stelem => 0xA4,
221 ClrOpcode::Ldlen => 0x8E,
222 ClrOpcode::Newarr => 0x8D,
223 ClrOpcode::Box => 0x8C,
224 ClrOpcode::Unbox => 0x79,
225 ClrOpcode::ConvI4 => 0x67,
226 ClrOpcode::ConvI8 => 0x68,
227 ClrOpcode::ConvR4 => 0x69,
228 ClrOpcode::ConvR8 => 0x6A,
229 ClrOpcode::LdindI4 => 0x4A,
230 ClrOpcode::LdindI8 => 0x4B,
231 ClrOpcode::LdindR4 => 0x4C,
232 ClrOpcode::LdindR8 => 0x4D,
233 ClrOpcode::LdindRef => 0x50,
234 ClrOpcode::StindI4 => 0x54,
235 ClrOpcode::StindI8 => 0x55,
236 ClrOpcode::StindR4 => 0x56,
237 ClrOpcode::StindR8 => 0x57,
238 ClrOpcode::StindRef => 0x51,
239 ClrOpcode::Throw => 0x7A,
240 }
241 }
242
243 pub fn from_str(s: &str) -> Option<Self> {
245 match s.to_lowercase().as_str() {
246 "nop" => Some(ClrOpcode::Nop),
247 "ldc.i4.m1" => Some(ClrOpcode::LdcI4M1),
248 "ldc.i4.0" => Some(ClrOpcode::LdcI40),
249 "ldc.i4.1" => Some(ClrOpcode::LdcI41),
250 "ldc.i4.2" => Some(ClrOpcode::LdcI42),
251 "ldc.i4.3" => Some(ClrOpcode::LdcI43),
252 "ldc.i4.4" => Some(ClrOpcode::LdcI44),
253 "ldc.i4.5" => Some(ClrOpcode::LdcI45),
254 "ldc.i4.6" => Some(ClrOpcode::LdcI46),
255 "ldc.i4.7" => Some(ClrOpcode::LdcI47),
256 "ldc.i4.8" => Some(ClrOpcode::LdcI48),
257 "ldc.i4.s" => Some(ClrOpcode::LdcI4S),
258 "ldc.i4" => Some(ClrOpcode::LdcI4),
259 "ldc.i8" => Some(ClrOpcode::LdcI8),
260 "ldc.r4" => Some(ClrOpcode::LdcR4),
261 "ldc.r8" => Some(ClrOpcode::LdcR8),
262 "ldnull" => Some(ClrOpcode::Ldnull),
263 "ldstr" => Some(ClrOpcode::Ldstr),
264 "ldarg.0" => Some(ClrOpcode::Ldarg0),
265 "ldarg.1" => Some(ClrOpcode::Ldarg1),
266 "ldarg.2" => Some(ClrOpcode::Ldarg2),
267 "ldarg.3" => Some(ClrOpcode::Ldarg3),
268 "ldloc.0" => Some(ClrOpcode::Ldloc0),
269 "ldloc.1" => Some(ClrOpcode::Ldloc1),
270 "ldloc.2" => Some(ClrOpcode::Ldloc2),
271 "ldloc.3" => Some(ClrOpcode::Ldloc3),
272 "stloc.0" => Some(ClrOpcode::Stloc0),
273 "stloc.1" => Some(ClrOpcode::Stloc1),
274 "stloc.2" => Some(ClrOpcode::Stloc2),
275 "stloc.3" => Some(ClrOpcode::Stloc3),
276 "call" => Some(ClrOpcode::Call),
277 "callvirt" => Some(ClrOpcode::Callvirt),
278 "ret" => Some(ClrOpcode::Ret),
279 "newobj" => Some(ClrOpcode::Newobj),
280 "pop" => Some(ClrOpcode::Pop),
281 "dup" => Some(ClrOpcode::Dup),
282 "add" => Some(ClrOpcode::Add),
283 "sub" => Some(ClrOpcode::Sub),
284 "mul" => Some(ClrOpcode::Mul),
285 "div" => Some(ClrOpcode::Div),
286 "ceq" => Some(ClrOpcode::Ceq),
287 "cgt" => Some(ClrOpcode::Cgt),
288 "clt" => Some(ClrOpcode::Clt),
289 "and" => Some(ClrOpcode::And),
290 "or" => Some(ClrOpcode::Or),
291 "br" => Some(ClrOpcode::Br),
292 "brtrue" => Some(ClrOpcode::Brtrue),
293 "brfalse" => Some(ClrOpcode::Brfalse),
294 "ldloc" => Some(ClrOpcode::Ldloc),
295 "stloc" => Some(ClrOpcode::Stloc),
296 "ldarg" => Some(ClrOpcode::Ldarg),
297 "starg" => Some(ClrOpcode::Starg),
298 "ldloca" => Some(ClrOpcode::Ldloca),
299 "ldfld" => Some(ClrOpcode::Ldfld),
300 "stfld" => Some(ClrOpcode::Stfld),
301 "ldelem" => Some(ClrOpcode::Ldelem),
302 "stelem" => Some(ClrOpcode::Stelem),
303 "ldlen" => Some(ClrOpcode::Ldlen),
304 "newarr" => Some(ClrOpcode::Newarr),
305 "box" => Some(ClrOpcode::Box),
306 "unbox" => Some(ClrOpcode::Unbox),
307 "conv.i4" => Some(ClrOpcode::ConvI4),
308 "conv.i8" => Some(ClrOpcode::ConvI8),
309 "conv.r4" => Some(ClrOpcode::ConvR4),
310 "conv.r8" => Some(ClrOpcode::ConvR8),
311 "ldind.i4" => Some(ClrOpcode::LdindI4),
312 "ldind.i8" => Some(ClrOpcode::LdindI8),
313 "ldind.r4" => Some(ClrOpcode::LdindR4),
314 "ldind.r8" => Some(ClrOpcode::LdindR8),
315 "ldind.ref" => Some(ClrOpcode::LdindRef),
316 "stind.i4" => Some(ClrOpcode::StindI4),
317 "stind.i8" => Some(ClrOpcode::StindI8),
318 "stind.r4" => Some(ClrOpcode::StindR4),
319 "stind.r8" => Some(ClrOpcode::StindR8),
320 "stind.ref" => Some(ClrOpcode::StindRef),
321 "throw" => Some(ClrOpcode::Throw),
322 _ => None,
323 }
324 }
325
326 pub fn as_str(&self) -> &'static str {
328 match self {
329 ClrOpcode::Nop => "nop",
330 ClrOpcode::LdcI4M1 => "ldc.i4.m1",
331 ClrOpcode::LdcI40 => "ldc.i4.0",
332 ClrOpcode::LdcI41 => "ldc.i4.1",
333 ClrOpcode::LdcI42 => "ldc.i4.2",
334 ClrOpcode::LdcI43 => "ldc.i4.3",
335 ClrOpcode::LdcI44 => "ldc.i4.4",
336 ClrOpcode::LdcI45 => "ldc.i4.5",
337 ClrOpcode::LdcI46 => "ldc.i4.6",
338 ClrOpcode::LdcI47 => "ldc.i4.7",
339 ClrOpcode::LdcI48 => "ldc.i4.8",
340 ClrOpcode::LdcI4S => "ldc.i4.s",
341 ClrOpcode::LdcI4 => "ldc.i4",
342 ClrOpcode::LdcI8 => "ldc.i8",
343 ClrOpcode::LdcR4 => "ldc.r4",
344 ClrOpcode::LdcR8 => "ldc.r8",
345 ClrOpcode::Ldnull => "ldnull",
346 ClrOpcode::Ldstr => "ldstr",
347 ClrOpcode::Ldarg0 => "ldarg.0",
348 ClrOpcode::Ldarg1 => "ldarg.1",
349 ClrOpcode::Ldarg2 => "ldarg.2",
350 ClrOpcode::Ldarg3 => "ldarg.3",
351 ClrOpcode::Ldloc0 => "ldloc.0",
352 ClrOpcode::Ldloc1 => "ldloc.1",
353 ClrOpcode::Ldloc2 => "ldloc.2",
354 ClrOpcode::Ldloc3 => "ldloc.3",
355 ClrOpcode::Stloc0 => "stloc.0",
356 ClrOpcode::Stloc1 => "stloc.1",
357 ClrOpcode::Stloc2 => "stloc.2",
358 ClrOpcode::Stloc3 => "stloc.3",
359 ClrOpcode::Call => "call",
360 ClrOpcode::Callvirt => "callvirt",
361 ClrOpcode::Ret => "ret",
362 ClrOpcode::Newobj => "newobj",
363 ClrOpcode::Pop => "pop",
364 ClrOpcode::Dup => "dup",
365 ClrOpcode::Add => "add",
366 ClrOpcode::Sub => "sub",
367 ClrOpcode::Mul => "mul",
368 ClrOpcode::Div => "div",
369 ClrOpcode::Ceq => "ceq",
370 ClrOpcode::Cgt => "cgt",
371 ClrOpcode::Clt => "clt",
372 ClrOpcode::And => "and",
373 ClrOpcode::Or => "or",
374 ClrOpcode::Br => "br",
375 ClrOpcode::Brtrue => "brtrue",
376 ClrOpcode::Brfalse => "brfalse",
377 ClrOpcode::Ldloc => "ldloc",
378 ClrOpcode::Stloc => "stloc",
379 ClrOpcode::Ldarg => "ldarg",
380 ClrOpcode::Starg => "starg",
381 ClrOpcode::Ldloca => "ldloca",
382 ClrOpcode::Ldfld => "ldfld",
383 ClrOpcode::Stfld => "stfld",
384 ClrOpcode::Ldelem => "ldelem",
385 ClrOpcode::Stelem => "stelem",
386 ClrOpcode::Ldlen => "ldlen",
387 ClrOpcode::Newarr => "newarr",
388 ClrOpcode::Box => "box",
389 ClrOpcode::Unbox => "unbox",
390 ClrOpcode::ConvI4 => "conv.i4",
391 ClrOpcode::ConvI8 => "conv.i8",
392 ClrOpcode::ConvR4 => "conv.r4",
393 ClrOpcode::ConvR8 => "conv.r8",
394 ClrOpcode::LdindI4 => "ldind.i4",
395 ClrOpcode::LdindI8 => "ldind.i8",
396 ClrOpcode::LdindR4 => "ldind.r4",
397 ClrOpcode::LdindR8 => "ldind.r8",
398 ClrOpcode::LdindRef => "ldind.ref",
399 ClrOpcode::StindI4 => "stind.i4",
400 ClrOpcode::StindI8 => "stind.i8",
401 ClrOpcode::StindR4 => "stind.r4",
402 ClrOpcode::StindR8 => "stind.r8",
403 ClrOpcode::StindRef => "stind.ref",
404 ClrOpcode::Throw => "throw",
405 }
406 }
407}
408
409#[derive(Debug, Clone, PartialEq)]
411pub struct ClrInstruction {
412 pub opcode: ClrOpcode,
414 pub operand: Option<ClrInstructionOperand>,
416 pub offset: u32,
418}
419
420#[derive(Debug, Clone, PartialEq)]
422pub enum ClrInstructionOperand {
423 Int32(i32),
425 Int64(i64),
427 Float32(f32),
429 Float64(f64),
431 String(String),
433 Type(ClrTypeReference),
435 Method(String, Option<String>, Vec<ClrTypeReference>, Box<ClrTypeReference>),
437 Field(String, Option<String>, Box<ClrTypeReference>),
439 Branch(i32),
441 Switch(Vec<i32>),
443}