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 FieldLayout(&mut self, field: id::Field, offset: u32) {
321 self.records.FieldLayout.push(rec::FieldLayout {
322 Offset: offset,
323 Field: field.0,
324 })
325 }
326
327 pub fn NestedClass(&mut self, inner: id::TypeDef, outer: id::TypeDef) {
328 debug_assert!(inner.0 > outer.0);
329
330 self.records.NestedClass.push(rec::NestedClass {
331 NestedClass: inner.0,
332 EnclosingClass: outer.0,
333 })
334 }
335
336 pub fn InterfaceImpl(&mut self, class: id::TypeDef, interface: &Type) -> id::InterfaceImpl {
337 let Type::Name(interface) = interface else {
338 panic!("invalid interfae type");
339 };
340
341 let interface = if interface.generics.is_empty() {
342 TypeDefOrRef::TypeRef(self.TypeRef(&interface.namespace, &interface.name))
343 } else {
344 TypeDefOrRef::TypeSpec(self.TypeSpec(
345 &interface.namespace,
346 &interface.name,
347 &interface.generics,
348 ))
349 };
350
351 id::InterfaceImpl(self.records.InterfaceImpl.push_pos(rec::InterfaceImpl {
352 Class: class,
353 Interface: interface,
354 }))
355 }
356
357 fn Type(&mut self, ty: &Type, buffer: &mut Vec<u8>) {
359 match ty {
360 Type::Void => buffer.push(ELEMENT_TYPE_VOID),
361 Type::Bool => buffer.push(ELEMENT_TYPE_BOOLEAN),
362 Type::Char => buffer.push(ELEMENT_TYPE_CHAR),
363 Type::I8 => buffer.push(ELEMENT_TYPE_I1),
364 Type::U8 => buffer.push(ELEMENT_TYPE_U1),
365 Type::I16 => buffer.push(ELEMENT_TYPE_I2),
366 Type::U16 => buffer.push(ELEMENT_TYPE_U2),
367 Type::I32 => buffer.push(ELEMENT_TYPE_I4),
368 Type::U32 => buffer.push(ELEMENT_TYPE_U4),
369 Type::I64 => buffer.push(ELEMENT_TYPE_I8),
370 Type::U64 => buffer.push(ELEMENT_TYPE_U8),
371 Type::F32 => buffer.push(ELEMENT_TYPE_R4),
372 Type::F64 => buffer.push(ELEMENT_TYPE_R8),
373 Type::ISize => buffer.push(ELEMENT_TYPE_I),
374 Type::USize => buffer.push(ELEMENT_TYPE_U),
375 Type::String => buffer.push(ELEMENT_TYPE_STRING),
376 Type::Object => buffer.push(ELEMENT_TYPE_OBJECT),
377
378 Type::Array(ty) => {
379 buffer.push(ELEMENT_TYPE_SZARRAY);
380 self.Type(ty, buffer);
381 }
382
383 Type::ArrayRef(ty) => {
384 buffer.push(ELEMENT_TYPE_BYREF);
385 buffer.push(ELEMENT_TYPE_SZARRAY);
386 self.Type(ty, buffer);
387 }
388
389 Type::RefMut(ty) => {
390 buffer.push(ELEMENT_TYPE_BYREF);
391 self.Type(ty, buffer);
392 }
393
394 Type::RefConst(ty) => {
395 buffer.write_compressed(ELEMENT_TYPE_CMOD_REQD as usize);
396 let pos = self.TypeRef("System.Runtime.CompilerServices", "IsConst");
397 buffer.write_compressed(TypeDefOrRef::TypeRef(pos).encode() as usize);
398 buffer.push(ELEMENT_TYPE_BYREF);
399 self.Type(ty, buffer);
400 }
401
402 Type::PtrMut(ty, pointers) => {
403 for _ in 0..*pointers {
404 buffer.write_compressed(ELEMENT_TYPE_PTR as usize);
405 }
406
407 self.Type(ty, buffer);
408 }
409
410 Type::PtrConst(ty, pointers) => {
411 buffer.write_compressed(ELEMENT_TYPE_CMOD_REQD as usize);
412 let pos = self.TypeRef("System.Runtime.CompilerServices", "IsConst");
413 buffer.write_compressed(TypeDefOrRef::TypeRef(pos).encode() as usize);
414
415 for _ in 0..*pointers {
416 buffer.write_compressed(ELEMENT_TYPE_PTR as usize);
417 }
418
419 self.Type(ty, buffer);
420 }
421
422 Type::ArrayFixed(ty, len) => {
423 buffer.push(ELEMENT_TYPE_ARRAY);
425 self.Type(ty, buffer);
426 buffer.write_compressed(1); buffer.write_compressed(1); buffer.write_compressed(*len); buffer.write_compressed(0); }
431
432 Type::Generic(number) => {
433 buffer.push(ELEMENT_TYPE_VAR);
434 buffer.write_compressed((*number) as usize);
435 }
436
437 Type::Name(ty) => self.TypeName(&ty.namespace, &ty.name, &ty.generics, buffer),
438 Type::AttributeEnum => buffer.push(0x55),
439 }
440 }
441
442 fn TypeName(&mut self, namespace: &str, name: &str, generics: &[Type], buffer: &mut Vec<u8>) {
443 if !generics.is_empty() {
444 buffer.push(ELEMENT_TYPE_GENERICINST);
445 }
446
447 let pos = self.TypeRef(namespace, name);
448 buffer.push(ELEMENT_TYPE_VALUETYPE);
451 buffer.write_compressed(TypeDefOrRef::TypeRef(pos).encode() as usize);
452
453 if !generics.is_empty() {
454 buffer.write_compressed(generics.len());
455
456 for ty in generics {
457 self.Type(ty, buffer);
458 }
459 }
460 }
461
462 fn FieldSig(&mut self, ty: &Type) -> id::BlobId {
464 let mut buffer = vec![0x6]; self.Type(ty, &mut buffer);
466 self.blobs.insert(&buffer)
467 }
468
469 fn MethodDefSig(&mut self, signature: &Signature) -> id::BlobId {
471 let mut buffer = vec![signature.flags.0];
472 buffer.write_compressed(signature.types.len());
473 self.Type(&signature.return_type, &mut buffer);
474
475 for ty in &signature.types {
476 self.Type(ty, &mut buffer);
477 }
478
479 self.blobs.insert(&buffer)
480 }
481
482 fn ConstantValue(&mut self, value: &Value) -> id::BlobId {
483 let mut buffer = vec![];
484 buffer.write_value(value);
485 self.blobs.insert(&buffer)
486 }
487
488 fn AttributeValue(&mut self, values: &[(String, Value)]) -> id::BlobId {
489 let mut buffer = vec![];
490 buffer.write_u16(1); let mut count = 0;
493
494 for (name, value) in values {
495 if name.is_empty() {
496 count += 1;
497 buffer.write_value(value);
498 } else {
499 break;
500 }
501 }
502
503 buffer.write_u16((values.len() - count).try_into().unwrap());
504
505 for (name, value) in &values[count..] {
506 buffer.push(0x53); buffer.push(value.ty().code());
508
509 if let Value::AttributeEnum(type_name, _) = value {
510 buffer.write_compressed(type_name.len());
511 buffer.extend_from_slice(type_name.as_bytes());
512 }
513
514 buffer.write_compressed(name.len());
515 buffer.extend_from_slice(name.as_bytes());
516 buffer.write_value(value);
517 }
518
519 self.blobs.insert(&buffer)
520 }
521}