1use gaia_types::{GaiaError, Result, SourceLocation};
2use oak_msil::ast as msil;
3use std::collections::HashMap;
4
5#[derive(Debug, Clone)]
10pub struct ClrProgram {
11 pub name: String,
13 pub version: ClrVersion,
15 pub access_flags: ClrAccessFlags,
17 pub external_assemblies: Vec<ClrExternalAssembly>,
19 pub module: Option<ClrModule>,
21 pub types: Vec<ClrType>,
23 pub global_methods: Vec<ClrMethod>,
25 pub global_fields: Vec<ClrField>,
27 pub attributes: Vec<ClrAttribute>,
29 pub constant_pool: ClrConstantPool,
31 pub source_file: Option<String>,
33}
34
35#[derive(Debug, Clone, Copy, PartialEq)]
37pub struct ClrVersion {
38 pub major: u16,
40 pub minor: u16,
42 pub build: u16,
44 pub revision: u16,
46}
47
48#[derive(Debug, Clone, Copy, PartialEq)]
50pub struct ClrAccessFlags {
51 pub is_public: bool,
53 pub is_private: bool,
55 pub is_security_transparent: bool,
57 pub is_retargetable: bool,
59}
60
61#[derive(Debug, Clone)]
63pub struct ClrExternalAssembly {
64 pub name: String,
66 pub version: ClrVersion,
68 pub public_key_token: Option<Vec<u8>>,
70 pub culture: Option<String>,
72 pub hash_algorithm: Option<u32>,
74}
75
76#[derive(Debug, Clone)]
78pub struct ClrModule {
79 pub name: String,
81 pub mvid: Option<Vec<u8>>,
83}
84
85#[derive(Debug, Clone)]
87pub struct ClrType {
88 pub name: String,
90 pub namespace: Option<String>,
92 pub access_flags: ClrAccessFlags,
94 pub base_type: Option<String>,
96 pub interfaces: Vec<String>,
98 pub fields: Vec<ClrField>,
100 pub methods: Vec<ClrMethod>,
102 pub properties: Vec<ClrProperty>,
104 pub events: Vec<ClrEvent>,
106 pub nested_types: Vec<ClrType>,
108 pub attributes: Vec<ClrAttribute>,
110}
111
112#[derive(Debug, Clone)]
114pub struct ClrMethod {
115 pub name: String,
117 pub return_type: ClrTypeReference,
119 pub parameters: Vec<ClrParameter>,
121 pub access_flags: ClrAccessFlags,
123 pub impl_flags: ClrMethodImplFlags,
125 pub instructions: Vec<ClrInstruction>,
127 pub max_stack: u16,
129 pub locals: Vec<ClrLocalVariable>,
131 pub exception_handlers: Vec<ClrExceptionHandler>,
133 pub attributes: Vec<ClrAttribute>,
135 pub is_entry_point: bool,
137}
138
139#[derive(Debug, Clone)]
141pub struct ClrField {
142 pub name: String,
144 pub field_type: ClrTypeReference,
146 pub access_flags: ClrAccessFlags,
148 pub default_value: Option<ClrConstantValue>,
150 pub attributes: Vec<ClrAttribute>,
152}
153
154#[derive(Debug, Clone)]
156pub struct ClrProperty {
157 pub name: String,
159 pub property_type: ClrTypeReference,
161 pub getter: Option<String>,
163 pub setter: Option<String>,
165 pub attributes: Vec<ClrAttribute>,
167}
168
169#[derive(Debug, Clone)]
171pub struct ClrEvent {
172 pub name: String,
174 pub event_type: ClrTypeReference,
176 pub add_method: Option<String>,
178 pub remove_method: Option<String>,
180 pub raise_method: Option<String>,
182 pub attributes: Vec<ClrAttribute>,
184}
185
186#[derive(Debug, Clone, PartialEq)]
188pub enum ClrInstruction {
189 Simple { opcode: ClrOpcode },
191 WithImmediate { opcode: ClrOpcode, value: i32 },
193 WithImmediate64 { opcode: ClrOpcode, value: i64 },
195 WithFloat32 { opcode: ClrOpcode, value: f32 },
197 WithFloat64 { opcode: ClrOpcode, value: f64 },
199 WithLocalVar { opcode: ClrOpcode, index: u16 },
201 WithParameter { opcode: ClrOpcode, index: u16 },
203 WithField { opcode: ClrOpcode, field_ref: String },
205 WithMethod { opcode: ClrOpcode, method_ref: String },
207 WithType { opcode: ClrOpcode, type_ref: String },
209 WithString { opcode: ClrOpcode, value: String },
211 WithLabel { opcode: ClrOpcode, label: String },
213 WithSwitch { opcode: ClrOpcode, labels: Vec<String> },
215}
216
217#[derive(Debug, Clone, Copy, PartialEq)]
219pub enum ClrOpcode {
220 Nop,
222 LdcI4,
223 LdcI4S,
224 LdcI4M1,
225 LdcI40,
226 LdcI41,
227 LdcI42,
228 LdcI43,
229 LdcI44,
230 LdcI45,
231 LdcI46,
232 LdcI47,
233 LdcI48,
234 LdcI8,
235 LdcR4,
236 LdcR8,
237 Ldnull,
238 Ldstr,
239
240 Ldarg,
242 LdargS,
243 Ldarg0,
244 Ldarg1,
245 Ldarg2,
246 Ldarg3,
247 Ldloc,
248 LdlocS,
249 Ldloc0,
250 Ldloc1,
251 Ldloc2,
252 Ldloc3,
253 Starg,
254 StargS,
255 Stloc,
256 StlocS,
257 Stloc0,
258 Stloc1,
259 Stloc2,
260 Stloc3,
261 Ldarga,
262 LdargaS,
263 Ldloca,
264 LdlocaS,
265
266 Ldelem,
268 LdelemI1,
269 LdelemU1,
270 LdelemI2,
271 LdelemU2,
272 LdelemI4,
273 LdelemU4,
274 LdelemI8,
275 LdelemI,
276 LdelemR4,
277 LdelemR8,
278 LdelemRef,
279 Stelem,
280 StelemI1,
281 StelemI2,
282 StelemI4,
283 StelemI8,
284 StelemI,
285 StelemR4,
286 StelemR8,
287 StelemRef,
288 Ldlen,
289 Newarr,
290
291 LdindI1,
293 LdindU1,
294 LdindI2,
295 LdindU2,
296 LdindI4,
297 LdindU4,
298 LdindI8,
299 LdindI,
300 LdindR4,
301 LdindR8,
302 LdindRef,
303 StindI1,
304 StindI2,
305 StindI4,
306 StindI8,
307 StindI,
308 StindR4,
309 StindR8,
310 StindRef,
311
312 Ldfld,
314 Ldflda,
315 Stfld,
316 Ldsfld,
317 Ldsflda,
318 Stsfld,
319
320 Call,
322 Callvirt,
323 Calli,
324 Ret,
325
326 Newobj,
328 Castclass,
329 Isinst,
330 Unbox,
331 UnboxAny,
332 Box,
333
334 Br,
336 BrS,
337 Brtrue,
338 BrtrueS,
339 Brfalse,
340 BrfalseS,
341 Beq,
342 BeqS,
343 Bne,
344 BneS,
345 Blt,
346 BltS,
347 BltUn,
348 BltUnS,
349 Ble,
350 BleS,
351 BleUn,
352 BleUnS,
353 Bgt,
354 BgtS,
355 BgtUn,
356 BgtUnS,
357 Bge,
358 BgeS,
359 BgeUn,
360 BgeUnS,
361 Switch,
362
363 Add,
365 AddOvf,
366 AddOvfUn,
367 Sub,
368 SubOvf,
369 SubOvfUn,
370 Mul,
371 MulOvf,
372 MulOvfUn,
373 Div,
374 DivUn,
375 Rem,
376 RemUn,
377 And,
378 Or,
379 Xor,
380 Not,
381 Shl,
382 Shr,
383 ShrUn,
384 Neg,
385
386 Ceq,
388 Cgt,
389 CgtUn,
390 Clt,
391 CltUn,
392
393 ConvI1,
395 ConvI2,
396 ConvI4,
397 ConvI8,
398 ConvR4,
399 ConvR8,
400 ConvU4,
401 ConvU8,
402 ConvOvfI1,
403 ConvOvfI2,
404 ConvOvfI4,
405 ConvOvfI8,
406 ConvOvfU1,
407 ConvOvfU2,
408 ConvOvfU4,
409 ConvOvfU8,
410 ConvOvfI1Un,
411 ConvOvfI2Un,
412 ConvOvfI4Un,
413 ConvOvfI8Un,
414 ConvOvfU1Un,
415 ConvOvfU2Un,
416 ConvOvfU4Un,
417 ConvOvfU8Un,
418 ConvRUn,
419 ConvOvfIUn,
420 ConvOvfUUn,
421
422 Dup,
424 Pop,
425
426 Throw,
428 Rethrow,
429 Leave,
430 LeaveS,
431 Endfinally,
432 Endfilter,
433
434 Sizeof,
436 Refanytype,
437 Refanyval,
438 Mkrefany,
439 Arglist,
440 Localloc,
441 Jmp,
442 Calli2,
443 Tail,
444 Volatile,
445 Unaligned,
446 Constrained,
447 Readonly,
448}
449
450#[derive(Debug, Clone, PartialEq)]
452pub struct ClrTypeReference {
453 pub name: String,
455 pub namespace: Option<String>,
457 pub assembly: Option<String>,
459 pub is_value_type: bool,
461 pub is_reference_type: bool,
463 pub generic_parameters: Vec<ClrTypeReference>,
465}
466
467#[derive(Debug, Clone)]
469pub struct ClrParameter {
470 pub name: String,
472 pub parameter_type: ClrTypeReference,
474 pub is_in: bool,
476 pub is_out: bool,
478 pub is_optional: bool,
480 pub default_value: Option<ClrConstantValue>,
482 pub attributes: Vec<ClrAttribute>,
484}
485
486#[derive(Debug, Clone)]
488pub struct ClrLocalVariable {
489 pub name: Option<String>,
491 pub variable_type: ClrTypeReference,
493 pub is_pinned: bool,
495}
496
497#[derive(Debug, Clone)]
499pub struct ClrExceptionHandler {
500 pub handler_type: ClrExceptionHandlerType,
502 pub try_start: u32,
504 pub try_length: u32,
506 pub handler_start: u32,
508 pub handler_length: u32,
510 pub catch_type: Option<ClrTypeReference>,
512 pub filter_start: Option<u32>,
514}
515
516#[derive(Debug, Clone, Copy, PartialEq)]
518pub enum ClrExceptionHandlerType {
519 Catch,
521 Filter,
523 Finally,
525 Fault,
527}
528
529#[derive(Debug, Clone, Copy, PartialEq)]
531pub struct ClrMethodImplFlags {
532 pub is_managed: bool,
534 pub is_native: bool,
536 pub is_runtime: bool,
538 pub is_inline: bool,
540 pub is_no_inline: bool,
542 pub is_synchronized: bool,
544}
545
546#[derive(Debug, Clone)]
548pub struct ClrAttribute {
549 pub attribute_type: ClrTypeReference,
551 pub constructor_args: Vec<ClrConstantValue>,
553 pub named_args: Vec<(String, ClrConstantValue)>,
555}
556
557#[derive(Debug, Clone, PartialEq)]
559pub enum ClrConstantValue {
560 Boolean(bool),
562 I1(i8),
564 U1(u8),
566 I2(i16),
568 U2(u16),
570 I4(i32),
572 U4(u32),
574 I8(i64),
576 U8(u64),
578 R4(f32),
580 R8(f64),
582 String(String),
584 Null,
586 Type(ClrTypeReference),
588 Enum(ClrTypeReference, Box<ClrConstantValue>),
590 Array(Vec<ClrConstantValue>),
592}
593
594#[derive(Debug, Clone)]
596pub struct ClrConstantPool {
597 pub strings: HashMap<String, u32>,
599 pub guids: HashMap<Vec<u8>, u32>,
601 pub blobs: HashMap<Vec<u8>, u32>,
603 pub user_strings: HashMap<String, u32>,
605}
606
607impl ClrProgram {
608 pub fn new(name: impl Into<String>) -> Self {
610 Self {
611 name: name.into(),
612 version: ClrVersion::default(),
613 access_flags: ClrAccessFlags::default(),
614 external_assemblies: Vec::new(),
615 module: None,
616 types: Vec::new(),
617 global_methods: Vec::new(),
618 global_fields: Vec::new(),
619 attributes: Vec::new(),
620 constant_pool: ClrConstantPool::new(),
621 source_file: None,
622 }
623 }
624
625 pub fn add_type(&mut self, clr_type: ClrType) {
627 self.types.push(clr_type);
628 }
629
630 pub fn add_external_assembly(&mut self, assembly: ClrExternalAssembly) {
632 self.external_assemblies.push(assembly);
633 }
634
635 pub fn set_module(&mut self, module: ClrModule) {
637 self.module = Some(module);
638 }
639
640 pub fn set_source_file(&mut self, filename: String) {
642 self.source_file = Some(filename);
643 }
644
645 pub fn validate(&self) -> Result<()> {
647 if self.name.is_empty() {
649 return Err(GaiaError::syntax_error("程序集名称不能为空".to_string(), SourceLocation::default()));
650 }
651
652 for clr_type in &self.types {
654 clr_type.validate()?;
655 }
656
657 Ok(())
658 }
659
660 pub fn get_type_count(&self) -> usize {
662 self.types.len()
663 }
664
665 pub fn get_method_count(&self) -> usize {
667 let type_methods: usize = self.types.iter().map(|t| t.methods.len()).sum();
668 type_methods + self.global_methods.len()
669 }
670
671 pub fn get_field_count(&self) -> usize {
673 let type_fields: usize = self.types.iter().map(|t| t.fields.len()).sum();
674 type_fields + self.global_fields.len()
675 }
676
677 pub fn get_sample_type_name(&self) -> Option<String> {
679 self.types.first().map(|t| {
680 if let Some(namespace) = &t.namespace {
681 format!("{}.{}", namespace, t.name)
682 }
683 else {
684 t.name.clone()
685 }
686 })
687 }
688
689 pub fn get_sample_method_name(&self) -> Option<String> {
691 for clr_type in &self.types {
693 if let Some(method) = clr_type.methods.first() {
694 return Some(format!("{}.{}", clr_type.name, method.name));
695 }
696 }
697 self.global_methods.first().map(|m| m.name.clone())
699 }
700
701 pub fn get_referenced_assemblies(&self) -> Vec<String> {
703 self.external_assemblies.iter().map(|a| a.name.clone()).collect()
704 }
705
706 pub fn to_msil(&self) -> msil::MsilRoot {
708 let mut items = Vec::new();
709
710 for ext in &self.external_assemblies {
712 items.push(msil::Item::AssemblyExtern(ext.name.clone()));
713 }
714
715 items.push(msil::Item::Assembly(msil::Assembly { name: self.name.clone(), span: (0..0usize).into() }));
717
718 if let Some(module) = &self.module {
720 items.push(msil::Item::Module(module.name.clone()));
721 }
722
723 for clr_type in &self.types {
725 items.push(msil::Item::Class(clr_type.to_msil()));
726 }
727
728 msil::MsilRoot { items }
729 }
730}
731
732impl ClrType {
733 fn to_msil(&self) -> msil::Class {
734 msil::Class {
735 name: self.name.clone(),
736 methods: self.methods.iter().map(|m| m.to_msil()).collect(),
737 span: (0..0usize).into(),
738 }
739 }
740}
741
742impl Default for ClrTypeReference {
743 fn default() -> Self {
744 Self {
745 name: "void".to_string(),
746 namespace: None,
747 assembly: None,
748 is_value_type: false,
749 is_reference_type: true,
750 generic_parameters: Vec::new(),
751 }
752 }
753}
754
755impl ClrTypeReference {
756 pub fn new(name: String) -> Self {
758 Self { name, ..Default::default() }
759 }
760}
761
762impl ClrMethod {
763 fn to_msil(&self) -> msil::Method {
764 msil::Method {
765 name: self.name.clone(),
766 instructions: self.instructions.iter().map(|i| i.to_msil()).collect(),
767 span: (0..0usize).into(),
768 }
769 }
770}
771
772impl ClrInstruction {
773 fn to_msil(&self) -> msil::Instruction {
774 match self {
775 ClrInstruction::Simple { opcode } => {
776 msil::Instruction { opcode: format!("{:?}", opcode).to_lowercase(), operand: None, span: (0..0usize).into() }
777 }
778 ClrInstruction::WithImmediate { opcode, value } => msil::Instruction {
779 opcode: format!("{:?}", opcode).to_lowercase(),
780 operand: Some(value.to_string()),
781 span: (0..0usize).into(),
782 },
783 ClrInstruction::WithImmediate64 { opcode, value } => msil::Instruction {
784 opcode: format!("{:?}", opcode).to_lowercase(),
785 operand: Some(value.to_string()),
786 span: (0..0usize).into(),
787 },
788 ClrInstruction::WithFloat32 { opcode, value } => msil::Instruction {
789 opcode: format!("{:?}", opcode).to_lowercase(),
790 operand: Some(value.to_string()),
791 span: (0..0usize).into(),
792 },
793 ClrInstruction::WithFloat64 { opcode, value } => msil::Instruction {
794 opcode: format!("{:?}", opcode).to_lowercase(),
795 operand: Some(value.to_string()),
796 span: (0..0usize).into(),
797 },
798 ClrInstruction::WithLocalVar { opcode, index } => msil::Instruction {
799 opcode: format!("{:?}", opcode).to_lowercase(),
800 operand: Some(index.to_string()),
801 span: (0..0usize).into(),
802 },
803 ClrInstruction::WithParameter { opcode, index } => msil::Instruction {
804 opcode: format!("{:?}", opcode).to_lowercase(),
805 operand: Some(index.to_string()),
806 span: (0..0usize).into(),
807 },
808 ClrInstruction::WithField { opcode, field_ref } => msil::Instruction {
809 opcode: format!("{:?}", opcode).to_lowercase(),
810 operand: Some(field_ref.clone()),
811 span: (0..0usize).into(),
812 },
813 ClrInstruction::WithMethod { opcode, method_ref } => msil::Instruction {
814 opcode: format!("{:?}", opcode).to_lowercase(),
815 operand: Some(method_ref.clone()),
816 span: (0..0usize).into(),
817 },
818 ClrInstruction::WithType { opcode, type_ref } => msil::Instruction {
819 opcode: format!("{:?}", opcode).to_lowercase(),
820 operand: Some(type_ref.clone()),
821 span: (0..0usize).into(),
822 },
823 ClrInstruction::WithString { opcode, value } => msil::Instruction {
824 opcode: format!("{:?}", opcode).to_lowercase(),
825 operand: Some(format!("\"{}\"", value)),
826 span: (0..0usize).into(),
827 },
828 ClrInstruction::WithLabel { opcode, label } => msil::Instruction {
829 opcode: format!("{:?}", opcode).to_lowercase(),
830 operand: Some(label.clone()),
831 span: (0..0usize).into(),
832 },
833 ClrInstruction::WithSwitch { opcode, labels } => msil::Instruction {
834 opcode: format!("{:?}", opcode).to_lowercase(),
835 operand: Some(labels.join(", ")),
836 span: (0..0usize).into(),
837 },
838 }
839 }
840}
841
842impl ClrConstantPool {
843 pub fn new() -> Self {
845 Self { strings: HashMap::new(), guids: HashMap::new(), blobs: HashMap::new(), user_strings: HashMap::new() }
846 }
847
848 pub fn add_string(&mut self, s: String) -> u32 {
850 let next_index = self.strings.len() as u32;
851 *self.strings.entry(s).or_insert(next_index)
852 }
853
854 pub fn add_guid(&mut self, guid: Vec<u8>) -> u32 {
856 let next_index = self.guids.len() as u32;
857 *self.guids.entry(guid).or_insert(next_index)
858 }
859
860 pub fn add_blob(&mut self, blob: Vec<u8>) -> u32 {
862 let next_index = self.blobs.len() as u32;
863 *self.blobs.entry(blob).or_insert(next_index)
864 }
865
866 pub fn add_user_string(&mut self, s: String) -> u32 {
868 let next_index = self.user_strings.len() as u32;
869 *self.user_strings.entry(s).or_insert(next_index)
870 }
871}
872
873impl ClrType {
874 pub fn new(name: String, namespace: Option<String>) -> Self {
876 Self {
877 name,
878 namespace,
879 access_flags: ClrAccessFlags::default(),
880 base_type: None,
881 interfaces: Vec::new(),
882 fields: Vec::new(),
883 methods: Vec::new(),
884 properties: Vec::new(),
885 events: Vec::new(),
886 nested_types: Vec::new(),
887 attributes: Vec::new(),
888 }
889 }
890
891 pub fn add_method(&mut self, method: ClrMethod) {
893 self.methods.push(method);
894 }
895
896 pub fn add_field(&mut self, field: ClrField) {
898 self.fields.push(field);
899 }
900
901 pub fn validate(&self) -> Result<()> {
903 if self.name.is_empty() {
905 return Err(GaiaError::syntax_error("类型名称不能为空".to_string(), SourceLocation::default()));
906 }
907
908 for method in &self.methods {
910 method.validate()?;
911 }
912
913 Ok(())
914 }
915}
916
917impl ClrMethod {
918 pub fn new(name: String, return_type: ClrTypeReference) -> Self {
920 Self {
921 name,
922 return_type,
923 parameters: Vec::new(),
924 access_flags: ClrAccessFlags::default(),
925 impl_flags: ClrMethodImplFlags::default(),
926 instructions: Vec::new(),
927 max_stack: 8,
928 locals: Vec::new(),
929 exception_handlers: Vec::new(),
930 attributes: Vec::new(),
931 is_entry_point: false,
932 }
933 }
934
935 pub fn add_instruction(&mut self, instruction: ClrInstruction) {
937 self.instructions.push(instruction);
938 }
939
940 pub fn add_parameter(&mut self, parameter: ClrParameter) {
942 self.parameters.push(parameter);
943 }
944
945 pub fn validate(&self) -> Result<()> {
947 if self.name.is_empty() {
949 return Err(GaiaError::syntax_error("方法名称不能为空".to_string(), SourceLocation::default()));
950 }
951
952 Ok(())
953 }
954}
955
956impl Default for ClrVersion {
957 fn default() -> Self {
958 Self { major: 0, minor: 0, build: 0, revision: 0 }
959 }
960}
961
962impl Default for ClrAccessFlags {
963 fn default() -> Self {
964 Self { is_public: false, is_private: true, is_security_transparent: false, is_retargetable: false }
965 }
966}
967
968impl Default for ClrMethodImplFlags {
969 fn default() -> Self {
970 Self {
971 is_managed: true,
972 is_native: false,
973 is_runtime: false,
974 is_inline: false,
975 is_no_inline: false,
976 is_synchronized: false,
977 }
978 }
979}
980
981impl ClrOpcode {
982 pub fn to_byte(&self) -> u8 {
984 match self {
985 ClrOpcode::Nop => 0x00,
986 ClrOpcode::LdcI4M1 => 0x15,
987 ClrOpcode::LdcI40 => 0x16,
988 ClrOpcode::LdcI41 => 0x17,
989 ClrOpcode::LdcI42 => 0x18,
990 ClrOpcode::LdcI43 => 0x19,
991 ClrOpcode::LdcI44 => 0x1A,
992 ClrOpcode::LdcI45 => 0x1B,
993 ClrOpcode::LdcI46 => 0x1C,
994 ClrOpcode::LdcI47 => 0x1D,
995 ClrOpcode::LdcI48 => 0x1E,
996 ClrOpcode::LdcI4S => 0x1F,
997 ClrOpcode::LdcI4 => 0x20,
998 ClrOpcode::LdcI8 => 0x21,
999 ClrOpcode::LdcR4 => 0x22,
1000 ClrOpcode::LdcR8 => 0x23,
1001 ClrOpcode::Ldnull => 0x14,
1002 ClrOpcode::Ldstr => 0x72,
1003 ClrOpcode::Ldarg0 => 0x02,
1004 ClrOpcode::Ldarg1 => 0x03,
1005 ClrOpcode::Ldarg2 => 0x04,
1006 ClrOpcode::Ldarg3 => 0x05,
1007 ClrOpcode::Ldloc0 => 0x06,
1008 ClrOpcode::Ldloc1 => 0x07,
1009 ClrOpcode::Ldloc2 => 0x08,
1010 ClrOpcode::Ldloc3 => 0x09,
1011 ClrOpcode::Stloc0 => 0x0A,
1012 ClrOpcode::Stloc1 => 0x0B,
1013 ClrOpcode::Stloc2 => 0x0C,
1014 ClrOpcode::Stloc3 => 0x0D,
1015 ClrOpcode::Call => 0x28,
1016 ClrOpcode::Callvirt => 0x6F,
1017 ClrOpcode::Ret => 0x2A,
1018 ClrOpcode::Newobj => 0x73,
1019 ClrOpcode::Pop => 0x26,
1020 ClrOpcode::Dup => 0x25,
1021 _ => 0x00, }
1023 }
1024
1025 pub fn from_str(s: &str) -> Option<Self> {
1027 match s.to_lowercase().as_str() {
1028 "nop" => Some(ClrOpcode::Nop),
1029 "ldc.i4.m1" => Some(ClrOpcode::LdcI4M1),
1030 "ldc.i4.0" => Some(ClrOpcode::LdcI40),
1031 "ldc.i4.1" => Some(ClrOpcode::LdcI41),
1032 "ldc.i4.2" => Some(ClrOpcode::LdcI42),
1033 "ldc.i4.3" => Some(ClrOpcode::LdcI43),
1034 "ldc.i4.4" => Some(ClrOpcode::LdcI44),
1035 "ldc.i4.5" => Some(ClrOpcode::LdcI45),
1036 "ldc.i4.6" => Some(ClrOpcode::LdcI46),
1037 "ldc.i4.7" => Some(ClrOpcode::LdcI47),
1038 "ldc.i4.8" => Some(ClrOpcode::LdcI48),
1039 "ldc.i4.s" => Some(ClrOpcode::LdcI4S),
1040 "ldc.i4" => Some(ClrOpcode::LdcI4),
1041 "ldc.i8" => Some(ClrOpcode::LdcI8),
1042 "ldc.r4" => Some(ClrOpcode::LdcR4),
1043 "ldc.r8" => Some(ClrOpcode::LdcR8),
1044 "ldnull" => Some(ClrOpcode::Ldnull),
1045 "ldstr" => Some(ClrOpcode::Ldstr),
1046 "ldarg.0" => Some(ClrOpcode::Ldarg0),
1047 "ldarg.1" => Some(ClrOpcode::Ldarg1),
1048 "ldarg.2" => Some(ClrOpcode::Ldarg2),
1049 "ldarg.3" => Some(ClrOpcode::Ldarg3),
1050 "ldloc.0" => Some(ClrOpcode::Ldloc0),
1051 "ldloc.1" => Some(ClrOpcode::Ldloc1),
1052 "ldloc.2" => Some(ClrOpcode::Ldloc2),
1053 "ldloc.3" => Some(ClrOpcode::Ldloc3),
1054 "stloc.0" => Some(ClrOpcode::Stloc0),
1055 "stloc.1" => Some(ClrOpcode::Stloc1),
1056 "stloc.2" => Some(ClrOpcode::Stloc2),
1057 "stloc.3" => Some(ClrOpcode::Stloc3),
1058 "call" => Some(ClrOpcode::Call),
1059 "callvirt" => Some(ClrOpcode::Callvirt),
1060 "ret" => Some(ClrOpcode::Ret),
1061 "newobj" => Some(ClrOpcode::Newobj),
1062 "pop" => Some(ClrOpcode::Pop),
1063 "dup" => Some(ClrOpcode::Dup),
1064 _ => None,
1065 }
1066 }
1067}
1068
1069#[derive(Copy, Debug, Clone)]
1074pub struct ClrHeader {
1075 pub cb: u32,
1077 pub major_runtime_version: u16,
1079 pub minor_runtime_version: u16,
1081 pub metadata_rva: u32,
1083 pub metadata_size: u32,
1085 pub flags: u32,
1087}
1088
1089#[derive(Debug, Clone)]
1091pub struct MetadataHeader {
1092 pub signature: u32,
1094 pub major_version: u16,
1096 pub minor_version: u16,
1098 pub reserved: u32,
1100 pub version_length: u32,
1102 pub version_string: String,
1104 pub flags: u16,
1106 pub streams: u16,
1108}
1109
1110#[derive(Debug, Clone)]
1112pub struct StreamHeader {
1113 pub offset: u32,
1115 pub size: u32,
1117 pub name: String,
1119}
1120
1121#[derive(Debug, Clone)]
1123pub struct DotNetAssemblyInfo {
1124 pub name: String,
1126 pub version: String,
1128 pub culture: Option<String>,
1130 pub public_key_token: Option<String>,
1132 pub runtime_version: Option<String>,
1134}