1use super::*;
2mod into_stream;
3
4mod rec;
5
6mod blobs;
7use blobs::*;
8
9mod strings;
10use strings::*;
11
12mod helpers;
13use helpers::*;
14
15#[derive(Default)]
17pub struct File {
18 strings: Strings,
19 blobs: Blobs,
20 records: rec::Records,
21
22 TypeRef: HashMap<String, HashMap<String, id::TypeRef>>,
24 AssemblyRef: HashMap<String, id::AssemblyRef>,
25 ModuleRef: HashMap<String, id::ModuleRef>,
26 MemberRef: HashMap<rec::MemberRef, id::MemberRef>,
27
28 Constant: BTreeMap<HasConstant, rec::Constant>,
30 Attribute: BTreeMap<HasAttribute, Vec<rec::Attribute>>,
31 GenericParam: BTreeMap<TypeOrMethodDef, Vec<rec::GenericParam>>,
32}
33
34impl File {
35 pub fn new(name: &str) -> Self {
37 let mut file = Self::default();
38
39 file.records.Assembly.push(rec::Assembly {
41 Name: file.strings.insert(name),
42 HashAlgId: 0x00008004,
43 MajorVersion: 0xFF,
44 MinorVersion: 0xFF,
45 BuildNumber: 0xFF,
46 RevisionNumber: 0xFF,
47 Flags: AssemblyFlags::WindowsRuntime,
48 ..Default::default()
49 });
50
51 file.records.Module.push(rec::Module {
53 Name: file.strings.insert(name),
54 Mvid: 1,
55 ..Default::default()
56 });
57
58 file.AssemblyRef("System");
60
61 file.TypeDef("", "<Module>", TypeDefOrRef::default(), TypeAttributes(0));
63
64 file
65 }
66
67 fn ModuleRef(&mut self, name: &str) -> id::ModuleRef {
68 if let Some(pos) = self.ModuleRef.get(name) {
69 return *pos;
70 }
71
72 let pos = id::ModuleRef(self.records.ModuleRef.push_pos(rec::ModuleRef {
73 Name: self.strings.insert(name),
74 }));
75
76 self.ModuleRef.insert(name.to_string(), pos);
77 pos
78 }
79
80 pub fn ImplMap(
81 &mut self,
82 method: id::MethodDef,
83 flags: PInvokeAttributes,
84 import_name: &str,
85 import_scope: &str,
86 ) {
87 let scope = self.ModuleRef(import_scope);
88
89 self.records.ImplMap.push(rec::ImplMap {
90 MappingFlags: flags,
91 MemberForwarded: MemberForwarded::MethodDef(method),
92 ImportName: self.strings.insert(import_name),
93 ImportScope: scope,
94 })
95 }
96
97 fn AssemblyRef(&mut self, namespace: &str) -> id::AssemblyRef {
99 let namespace = namespace
102 .split_once('.')
103 .map_or(namespace, |(prefix, _)| prefix);
104
105 if let Some(pos) = self.AssemblyRef.get(namespace) {
106 return *pos;
107 }
108
109 let pos = id::AssemblyRef(if namespace == "System" {
110 self.records.AssemblyRef.push_pos(rec::AssemblyRef {
111 Name: self.strings.insert("mscorlib"),
112 MajorVersion: 4,
113 PublicKeyOrToken: self
114 .blobs
115 .insert(&[0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89]),
116 ..Default::default()
117 })
118 } else {
119 self.records.AssemblyRef.push_pos(rec::AssemblyRef {
120 Name: self.strings.insert(namespace),
121 MajorVersion: 0xFF,
122 MinorVersion: 0xFF,
123 BuildNumber: 0xFF,
124 RevisionNumber: 0xFF,
125 Flags: AssemblyFlags::WindowsRuntime,
126 ..Default::default()
127 })
128 });
129
130 self.AssemblyRef.insert(namespace.to_string(), pos);
131 pos
132 }
133
134 pub fn TypeDef(
136 &mut self,
137 namespace: &str,
138 name: &str,
139 extends: TypeDefOrRef,
140 flags: TypeAttributes,
141 ) -> id::TypeDef {
142 id::TypeDef(self.records.TypeDef.push_pos(rec::TypeDef {
143 TypeName: self.strings.insert(name),
144 TypeNamespace: self.strings.insert(namespace),
145 Flags: flags,
146 Extends: extends,
147 FieldList: self.records.Field.len() as u32,
148 MethodList: self.records.MethodDef.len() as u32,
149 }))
150 }
151
152 pub fn TypeRef(&mut self, namespace: &str, name: &str) -> id::TypeRef {
154 if let Some(key) = self.TypeRef.get(namespace) {
155 if let Some(pos) = key.get(name) {
156 return *pos;
157 }
158 }
159
160 let scope = ResolutionScope::AssemblyRef(self.AssemblyRef(namespace));
162
163 let pos = id::TypeRef(self.records.TypeRef.push_pos(rec::TypeRef {
164 TypeName: self.strings.insert(name),
165 TypeNamespace: self.strings.insert(namespace),
166 ResolutionScope: scope,
167 }));
168
169 self.TypeRef
170 .entry(namespace.to_string())
171 .or_default()
172 .insert(name.to_string(), pos);
173
174 pos
175 }
176
177 pub fn TypeSpec(&mut self, namespace: &str, name: &str, generics: &[Type]) -> id::TypeSpec {
178 debug_assert!(!generics.is_empty());
179
180 let type_ref = self.TypeRef(namespace, name);
181
182 let mut buffer = vec![];
183 buffer.push(ELEMENT_TYPE_GENERICINST);
184 buffer.push(ELEMENT_TYPE_CLASS);
185 buffer.write_compressed(TypeDefOrRef::TypeRef(type_ref).encode() as usize);
186 buffer.write_compressed(generics.len());
187
188 for ty in generics {
189 self.Type(ty, &mut buffer);
190 }
191
192 id::TypeSpec(self.records.TypeSpec.push_pos(rec::TypeSpec {
194 Signature: self.blobs.insert(&buffer),
195 }))
196 }
197
198 pub fn Field(&mut self, name: &str, ty: &Type, flags: FieldAttributes) -> id::Field {
200 let signature = self.FieldSig(ty);
201
202 id::Field(self.records.Field.push_pos(rec::Field {
203 Name: self.strings.insert(name),
204 Flags: flags,
205 Signature: signature,
206 }))
207 }
208
209 pub fn MethodDef(
211 &mut self,
212 name: &str,
213 signature: &Signature,
214 flags: MethodAttributes,
215 impl_flags: MethodImplAttributes,
216 ) -> id::MethodDef {
217 let signature = self.MethodDefSig(signature);
218
219 id::MethodDef(self.records.MethodDef.push_pos(rec::MethodDef {
220 RVA: 0,
221 ImplFlags: impl_flags,
222 Flags: flags,
223 Name: self.strings.insert(name),
224 Signature: signature,
225 ParamList: self.records.Param.len() as u32,
226 }))
227 }
228
229 pub fn MemberRef(
230 &mut self,
231 name: &str,
232 signature: &Signature,
233 parent: MemberRefParent,
234 ) -> id::MemberRef {
235 let signature = self.MethodDefSig(signature);
236
237 let record = rec::MemberRef {
238 Name: self.strings.insert(name),
239 Signature: signature,
240 Parent: parent,
241 };
242
243 if let Some(pos) = self.MemberRef.get(&record) {
244 return *pos;
245 }
246
247 let pos = id::MemberRef(self.records.MemberRef.push_pos(record));
248 self.MemberRef.insert(record, pos);
249 pos
250 }
251
252 pub fn Param(&mut self, name: &str, sequence: u16, flags: ParamAttributes) -> id::Param {
254 id::Param(self.records.Param.push_pos(rec::Param {
255 Flags: flags,
256 Sequence: sequence,
257 Name: self.strings.insert(name),
258 }))
259 }
260
261 pub fn Attribute(
263 &mut self,
264 parent: HasAttribute,
265 ty: AttributeType,
266 value: &[(String, Value)],
267 ) {
268 let value = self.AttributeValue(value);
269
270 self.Attribute
271 .entry(parent)
272 .or_default()
273 .push(rec::Attribute {
274 Parent: parent,
275 Type: ty,
276 Value: value,
277 });
278 }
279
280 pub fn Constant(&mut self, parent: HasConstant, value: &Value) {
281 let ty = value.ty().code();
282 let value = self.ConstantValue(value);
283
284 self.Constant.insert(
285 parent,
286 rec::Constant {
287 Parent: parent,
288 Type: ty,
289 Value: value,
290 },
291 );
292 }
293
294 pub fn GenericParam(
295 &mut self,
296 name: &str,
297 owner: TypeOrMethodDef,
298 number: u16,
299 flags: GenericParamAttributes,
300 ) {
301 self.GenericParam
302 .entry(owner)
303 .or_default()
304 .push(rec::GenericParam {
305 Name: self.strings.insert(name),
306 Number: number,
307 Owner: owner,
308 Flags: flags,
309 });
310 }
311
312 pub fn ClassLayout(&mut self, parent: id::TypeDef, packing_size: u16, class_size: u32) {
313 self.records.ClassLayout.push(rec::ClassLayout {
314 PackingSize: packing_size,
315 ClassSize: class_size,
316 Parent: parent.0,
317 })
318 }
319
320 pub fn NestedClass(&mut self, inner: id::TypeDef, outer: id::TypeDef) {
321 debug_assert!(inner.0 > outer.0);
322
323 self.records.NestedClass.push(rec::NestedClass {
324 NestedClass: inner.0,
325 EnclosingClass: outer.0,
326 })
327 }
328
329 pub fn InterfaceImpl(&mut self, class: id::TypeDef, interface: &Type) -> id::InterfaceImpl {
330 let Type::Name(interface) = interface else {
331 panic!("invalid interfae type");
332 };
333
334 let interface = if interface.generics.is_empty() {
335 TypeDefOrRef::TypeRef(self.TypeRef(&interface.namespace, &interface.name))
336 } else {
337 TypeDefOrRef::TypeSpec(self.TypeSpec(
338 &interface.namespace,
339 &interface.name,
340 &interface.generics,
341 ))
342 };
343
344 id::InterfaceImpl(self.records.InterfaceImpl.push_pos(rec::InterfaceImpl {
345 Class: class,
346 Interface: interface,
347 }))
348 }
349
350 fn Type(&mut self, ty: &Type, buffer: &mut Vec<u8>) {
352 match ty {
353 Type::Void => buffer.push(ELEMENT_TYPE_VOID),
354 Type::Bool => buffer.push(ELEMENT_TYPE_BOOLEAN),
355 Type::Char => buffer.push(ELEMENT_TYPE_CHAR),
356 Type::I8 => buffer.push(ELEMENT_TYPE_I1),
357 Type::U8 => buffer.push(ELEMENT_TYPE_U1),
358 Type::I16 => buffer.push(ELEMENT_TYPE_I2),
359 Type::U16 => buffer.push(ELEMENT_TYPE_U2),
360 Type::I32 => buffer.push(ELEMENT_TYPE_I4),
361 Type::U32 => buffer.push(ELEMENT_TYPE_U4),
362 Type::I64 => buffer.push(ELEMENT_TYPE_I8),
363 Type::U64 => buffer.push(ELEMENT_TYPE_U8),
364 Type::F32 => buffer.push(ELEMENT_TYPE_R4),
365 Type::F64 => buffer.push(ELEMENT_TYPE_R8),
366 Type::ISize => buffer.push(ELEMENT_TYPE_I),
367 Type::USize => buffer.push(ELEMENT_TYPE_U),
368 Type::String => buffer.push(ELEMENT_TYPE_STRING),
369 Type::Object => buffer.push(ELEMENT_TYPE_OBJECT),
370
371 Type::Array(ty) => {
372 buffer.push(ELEMENT_TYPE_SZARRAY);
373 self.Type(ty, buffer);
374 }
375
376 Type::ArrayRef(ty) => {
377 buffer.push(ELEMENT_TYPE_BYREF);
378 buffer.push(ELEMENT_TYPE_SZARRAY);
379 self.Type(ty, buffer);
380 }
381
382 Type::ConstRef(ty) => {
383 buffer.write_compressed(ELEMENT_TYPE_CMOD_REQD as usize);
384 let pos = self.TypeRef("System.Runtime.CompilerServices", "IsConst");
385 buffer.write_compressed(TypeDefOrRef::TypeRef(pos).encode() as usize);
386 self.Type(ty, buffer);
387 }
388
389 Type::PtrMut(ty, pointers) => {
390 for _ in 0..*pointers {
391 buffer.write_compressed(ELEMENT_TYPE_PTR as usize);
392 }
393
394 self.Type(ty, buffer);
395 }
396
397 Type::PtrConst(ty, pointers) => {
398 buffer.write_compressed(ELEMENT_TYPE_CMOD_REQD as usize);
399 let pos = self.TypeRef("System.Runtime.CompilerServices", "IsConst");
400 buffer.write_compressed(TypeDefOrRef::TypeRef(pos).encode() as usize);
401
402 for _ in 0..*pointers {
403 buffer.write_compressed(ELEMENT_TYPE_PTR as usize);
404 }
405
406 self.Type(ty, buffer);
407 }
408
409 Type::ArrayFixed(ty, len) => {
410 buffer.push(ELEMENT_TYPE_ARRAY);
412 self.Type(ty, buffer);
413 buffer.write_compressed(1); buffer.write_compressed(1); buffer.write_compressed(*len); buffer.write_compressed(0); }
418
419 Type::Generic(number) => {
420 buffer.push(ELEMENT_TYPE_VAR);
421 buffer.write_compressed((*number) as usize);
422 }
423
424 Type::Name(ty) => self.TypeName(&ty.namespace, &ty.name, &ty.generics, buffer),
425 Type::AttributeEnum => buffer.push(0x55),
426 }
427 }
428
429 fn TypeName(&mut self, namespace: &str, name: &str, generics: &[Type], buffer: &mut Vec<u8>) {
430 if !generics.is_empty() {
431 buffer.push(ELEMENT_TYPE_GENERICINST);
432 }
433
434 let pos = self.TypeRef(namespace, name);
435 buffer.push(ELEMENT_TYPE_VALUETYPE);
438 buffer.write_compressed(TypeDefOrRef::TypeRef(pos).encode() as usize);
439
440 if !generics.is_empty() {
441 buffer.write_compressed(generics.len());
442
443 for ty in generics {
444 self.Type(ty, buffer);
445 }
446 }
447 }
448
449 fn FieldSig(&mut self, ty: &Type) -> id::BlobId {
451 let mut buffer = vec![0x6]; self.Type(ty, &mut buffer);
453 self.blobs.insert(&buffer)
454 }
455
456 fn MethodDefSig(&mut self, signature: &Signature) -> id::BlobId {
458 let mut buffer = vec![signature.flags.0];
459 buffer.write_compressed(signature.types.len());
460 self.Type(&signature.return_type, &mut buffer);
461
462 for ty in &signature.types {
463 self.Type(ty, &mut buffer);
464 }
465
466 self.blobs.insert(&buffer)
467 }
468
469 fn ConstantValue(&mut self, value: &Value) -> id::BlobId {
470 let mut buffer = vec![];
471 buffer.write_value(value);
472 self.blobs.insert(&buffer)
473 }
474
475 fn AttributeValue(&mut self, values: &[(String, Value)]) -> id::BlobId {
476 let mut buffer = vec![];
477 buffer.write_u16(1); let mut count = 0;
480
481 for (name, value) in values {
482 if name.is_empty() {
483 count += 1;
484 buffer.write_value(value);
485 } else {
486 break;
487 }
488 }
489
490 buffer.write_u16((values.len() - count).try_into().unwrap());
491
492 for (name, value) in &values[count..] {
493 buffer.push(0x53); buffer.push(value.ty().code());
495
496 if let Value::AttributeEnum(type_name, _) = value {
497 buffer.write_compressed(type_name.len());
498 buffer.extend_from_slice(type_name.as_bytes());
499 }
500
501 buffer.write_compressed(name.len());
502 buffer.extend_from_slice(name.as_bytes());
503 buffer.write_value(value);
504 }
505
506 self.blobs.insert(&buffer)
507 }
508}