5
// Jb Evain (jbevain@gmail.com)
7
// Copyright (c) 2008 - 2010 Jb Evain
9
// Permission is hereby granted, free of charge, to any person obtaining
10
// a copy of this software and associated documentation files (the
11
// "Software"), to deal in the Software without restriction, including
12
// without limitation the rights to use, copy, modify, merge, publish,
13
// distribute, sublicense, and/or sell copies of the Software, and to
14
// permit persons to whom the Software is furnished to do so, subject to
15
// the following conditions:
17
// The above copyright notice and this permission notice shall be
18
// included in all copies or substantial portions of the Software.
20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
using System.Collections.Generic;
34
using Mono.Collections.Generic;
36
using Mono.Cecil.Metadata;
39
using RVA = System.UInt32;
40
using RID = System.UInt32;
41
using CodedRID = System.UInt32;
42
using StringIndex = System.UInt32;
43
using BlobIndex = System.UInt32;
45
namespace Mono.Cecil {
49
using TypeRefRow = Row<CodedRID, StringIndex, StringIndex>;
50
using TypeDefRow = Row<TypeAttributes, StringIndex, StringIndex, CodedRID, RID, RID>;
51
using FieldRow = Row<FieldAttributes, StringIndex, BlobIndex>;
52
using MethodRow = Row<RVA, MethodImplAttributes, MethodAttributes, StringIndex, BlobIndex, RID>;
53
using ParamRow = Row<ParameterAttributes, ushort, StringIndex>;
54
using InterfaceImplRow = Row<uint, CodedRID>;
55
using MemberRefRow = Row<CodedRID, StringIndex, BlobIndex>;
56
using ConstantRow = Row<ElementType, CodedRID, BlobIndex>;
57
using CustomAttributeRow = Row<CodedRID, CodedRID, BlobIndex>;
58
using FieldMarshalRow = Row<CodedRID, BlobIndex>;
59
using DeclSecurityRow = Row<SecurityAction, CodedRID, BlobIndex>;
60
using ClassLayoutRow = Row<ushort, uint, RID>;
61
using FieldLayoutRow = Row<uint, RID>;
62
using EventMapRow = Row<RID, RID>;
63
using EventRow = Row<EventAttributes, StringIndex, CodedRID>;
64
using PropertyMapRow = Row<RID, RID>;
65
using PropertyRow = Row<PropertyAttributes, StringIndex, BlobIndex>;
66
using MethodSemanticsRow = Row<MethodSemanticsAttributes, RID, CodedRID>;
67
using MethodImplRow = Row<RID, CodedRID, CodedRID>;
68
using ImplMapRow = Row<PInvokeAttributes, CodedRID, StringIndex, RID>;
69
using FieldRVARow = Row<RVA, RID>;
70
using AssemblyRow = Row<AssemblyHashAlgorithm, ushort, ushort, ushort, ushort, AssemblyAttributes, uint, uint, uint>;
71
using AssemblyRefRow = Row<ushort, ushort, ushort, ushort, AssemblyAttributes, uint, uint, uint, uint>;
72
using FileRow = Row<FileAttributes, StringIndex, BlobIndex>;
73
using ExportedTypeRow = Row<TypeAttributes, uint, StringIndex, StringIndex, CodedRID>;
74
using ManifestResourceRow = Row<uint, ManifestResourceAttributes, StringIndex, CodedRID>;
75
using NestedClassRow = Row<RID, RID>;
76
using GenericParamRow = Row<ushort, GenericParameterAttributes, CodedRID, StringIndex>;
77
using MethodSpecRow = Row<CodedRID, BlobIndex>;
78
using GenericParamConstraintRow = Row<RID, CodedRID>;
80
static class ModuleWriter {
82
public static void WriteModuleTo (ModuleDefinition module, Stream stream, WriterParameters parameters)
84
if ((module.Attributes & ModuleAttributes.ILOnly) == 0)
85
throw new ArgumentException ();
87
if (module.HasImage && module.ReadingMode == ReadingMode.Deferred)
88
ImmediateModuleReader.ReadModule (module);
90
module.MetadataSystem.Clear ();
92
var name = module.assembly != null ? module.assembly.Name : null;
93
var fq_name = stream.GetFullyQualifiedName ();
94
var symbol_writer_provider = parameters.SymbolWriterProvider;
95
if (symbol_writer_provider == null && parameters.WriteSymbols)
96
symbol_writer_provider = SymbolProvider.GetPlatformWriterProvider ();
97
var symbol_writer = GetSymbolWriter (module, fq_name, symbol_writer_provider);
99
#if !SILVERLIGHT && !CF
100
if (parameters.StrongNameKeyPair != null && name != null)
101
name.PublicKey = parameters.StrongNameKeyPair.PublicKey;
104
if (name != null && name.HasPublicKey)
105
module.Attributes |= ModuleAttributes.StrongNameSigned;
107
var metadata = new MetadataBuilder (module, fq_name,
108
symbol_writer_provider, symbol_writer);
110
BuildMetadata (module, metadata);
112
if (module.SymbolReader != null)
113
module.SymbolReader.Dispose ();
115
var writer = ImageWriter.CreateWriter (module, metadata, stream);
117
writer.WriteImage ();
119
#if !SILVERLIGHT && !CF
120
if (parameters.StrongNameKeyPair != null)
121
CryptoService.StrongName (stream, writer, parameters.StrongNameKeyPair);
123
if (symbol_writer != null)
124
symbol_writer.Dispose ();
127
static void BuildMetadata (ModuleDefinition module, MetadataBuilder metadata)
129
if (!module.HasImage) {
130
metadata.BuildMetadata ();
134
module.Read (metadata, (builder, _) => {
135
builder.BuildMetadata ();
140
static ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fq_name, ISymbolWriterProvider symbol_writer_provider)
142
if (symbol_writer_provider == null)
145
return symbol_writer_provider.GetSymbolWriter (module, fq_name);
149
abstract class MetadataTable {
151
public abstract int Length { get; }
153
public bool IsLarge {
154
get { return Length > 65535; }
157
public abstract void Write (TableHeapBuffer buffer);
158
public abstract void Sort ();
161
abstract class OneRowTable<TRow> : MetadataTable where TRow : struct {
165
public sealed override int Length {
169
public sealed override void Sort ()
174
abstract class MetadataTable<TRow> : MetadataTable where TRow : struct {
176
internal TRow [] rows = new TRow [2];
179
public sealed override int Length {
180
get { return length; }
183
public int AddRow (TRow row)
185
if (rows.Length == length)
188
rows [length++] = row;
194
var rows = new TRow [this.rows.Length * 2];
195
Array.Copy (this.rows, rows, this.rows.Length);
199
public override void Sort ()
204
abstract class SortedTable<TRow> : MetadataTable<TRow>, IComparer<TRow> where TRow : struct {
206
public sealed override void Sort ()
208
Array.Sort (rows, 0, length, this);
211
protected int Compare (uint x, uint y)
213
return x == y ? 0 : x > y ? 1 : -1;
216
public abstract int Compare (TRow x, TRow y);
219
sealed class ModuleTable : OneRowTable<uint> {
221
public override void Write (TableHeapBuffer buffer)
223
buffer.WriteUInt16 (0); // Generation
224
buffer.WriteString (row); // Name
225
buffer.WriteUInt16 (1); // Mvid
226
buffer.WriteUInt16 (0); // EncId
227
buffer.WriteUInt16 (0); // EncBaseId
231
sealed class TypeRefTable : MetadataTable<TypeRefRow> {
233
public override void Write (TableHeapBuffer buffer)
235
for (int i = 0; i < length; i++) {
236
buffer.WriteCodedRID (
237
rows [i].Col1, CodedIndex.ResolutionScope); // Scope
238
buffer.WriteString (rows [i].Col2); // Name
239
buffer.WriteString (rows [i].Col3); // Namespace
244
sealed class TypeDefTable : MetadataTable<TypeDefRow> {
246
public override void Write (TableHeapBuffer buffer)
248
for (int i = 0; i < length; i++) {
249
buffer.WriteUInt32 ((uint) rows [i].Col1); // Attributes
250
buffer.WriteString (rows [i].Col2); // Name
251
buffer.WriteString (rows [i].Col3); // Namespace
252
buffer.WriteCodedRID (
253
rows [i].Col4, CodedIndex.TypeDefOrRef); // Extends
254
buffer.WriteRID (rows [i].Col5, Table.Field); // FieldList
255
buffer.WriteRID (rows [i].Col6, Table.Method); // MethodList
260
sealed class FieldTable : MetadataTable<FieldRow> {
262
public override void Write (TableHeapBuffer buffer)
264
for (int i = 0; i < length; i++) {
265
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes
266
buffer.WriteString (rows [i].Col2); // Name
267
buffer.WriteBlob (rows [i].Col3); // Signature
272
sealed class MethodTable : MetadataTable<MethodRow> {
274
public override void Write (TableHeapBuffer buffer)
276
for (int i = 0; i < length; i++) {
277
buffer.WriteUInt32 (rows [i].Col1); // RVA
278
buffer.WriteUInt16 ((ushort) rows [i].Col2); // ImplFlags
279
buffer.WriteUInt16 ((ushort) rows [i].Col3); // Flags
280
buffer.WriteString (rows [i].Col4); // Name
281
buffer.WriteBlob (rows [i].Col5); // Signature
282
buffer.WriteRID (rows [i].Col6, Table.Param); // ParamList
287
sealed class ParamTable : MetadataTable<ParamRow> {
289
public override void Write (TableHeapBuffer buffer)
291
for (int i = 0; i < length; i++) {
292
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes
293
buffer.WriteUInt16 (rows [i].Col2); // Sequence
294
buffer.WriteString (rows [i].Col3); // Name
299
sealed class InterfaceImplTable : MetadataTable<InterfaceImplRow> {
301
public override void Write (TableHeapBuffer buffer)
303
for (int i = 0; i < length; i++) {
304
buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class
305
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Interface
309
/*public override int Compare (InterfaceImplRow x, InterfaceImplRow y)
311
return (int) (x.Col1 == y.Col1 ? y.Col2 - x.Col2 : x.Col1 - y.Col1);
315
sealed class MemberRefTable : MetadataTable<MemberRefRow> {
317
public override void Write (TableHeapBuffer buffer)
319
for (int i = 0; i < length; i++) {
320
buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MemberRefParent);
321
buffer.WriteString (rows [i].Col2);
322
buffer.WriteBlob (rows [i].Col3);
327
sealed class ConstantTable : SortedTable<ConstantRow> {
329
public override void Write (TableHeapBuffer buffer)
331
for (int i = 0; i < length; i++) {
332
buffer.WriteUInt16 ((ushort) rows [i].Col1);
333
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasConstant);
334
buffer.WriteBlob (rows [i].Col3);
338
public override int Compare (ConstantRow x, ConstantRow y)
340
return Compare (x.Col2, y.Col2);
344
sealed class CustomAttributeTable : SortedTable<CustomAttributeRow> {
346
public override void Write (TableHeapBuffer buffer)
348
for (int i = 0; i < length; i++) {
349
buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasCustomAttribute); // Parent
350
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.CustomAttributeType); // Type
351
buffer.WriteBlob (rows [i].Col3);
355
public override int Compare (CustomAttributeRow x, CustomAttributeRow y)
357
return Compare (x.Col1, y.Col1);
361
sealed class FieldMarshalTable : SortedTable<FieldMarshalRow> {
363
public override void Write (TableHeapBuffer buffer)
365
for (int i = 0; i < length; i++) {
366
buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasFieldMarshal);
367
buffer.WriteBlob (rows [i].Col2);
371
public override int Compare (FieldMarshalRow x, FieldMarshalRow y)
373
return Compare (x.Col1, y.Col1);
377
sealed class DeclSecurityTable : SortedTable<DeclSecurityRow> {
379
public override void Write (TableHeapBuffer buffer)
381
for (int i = 0; i < length; i++) {
382
buffer.WriteUInt16 ((ushort) rows [i].Col1);
383
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasDeclSecurity);
384
buffer.WriteBlob (rows [i].Col3);
388
public override int Compare (DeclSecurityRow x, DeclSecurityRow y)
390
return Compare (x.Col2, y.Col2);
394
sealed class ClassLayoutTable : SortedTable<ClassLayoutRow> {
396
public override void Write (TableHeapBuffer buffer)
398
for (int i = 0; i < length; i++) {
399
buffer.WriteUInt16 (rows [i].Col1); // PackingSize
400
buffer.WriteUInt32 (rows [i].Col2); // ClassSize
401
buffer.WriteRID (rows [i].Col3, Table.TypeDef); // Parent
405
public override int Compare (ClassLayoutRow x, ClassLayoutRow y)
407
return Compare (x.Col3, y.Col3);
411
sealed class FieldLayoutTable : SortedTable<FieldLayoutRow> {
413
public override void Write (TableHeapBuffer buffer)
415
for (int i = 0; i < length; i++) {
416
buffer.WriteUInt32 (rows [i].Col1); // Offset
417
buffer.WriteRID (rows [i].Col2, Table.Field); // Parent
421
public override int Compare (FieldLayoutRow x, FieldLayoutRow y)
423
return Compare (x.Col2, y.Col2);
427
sealed class StandAloneSigTable : MetadataTable<uint> {
429
public override void Write (TableHeapBuffer buffer)
431
for (int i = 0; i < length; i++)
432
buffer.WriteBlob (rows [i]);
436
sealed class EventMapTable : MetadataTable<EventMapRow> {
438
public override void Write (TableHeapBuffer buffer)
440
for (int i = 0; i < length; i++) {
441
buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent
442
buffer.WriteRID (rows [i].Col2, Table.Event); // EventList
447
sealed class EventTable : MetadataTable<EventRow> {
449
public override void Write (TableHeapBuffer buffer)
451
for (int i = 0; i < length; i++) {
452
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
453
buffer.WriteString (rows [i].Col2); // Name
454
buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeDefOrRef); // EventType
459
sealed class PropertyMapTable : MetadataTable<PropertyMapRow> {
461
public override void Write (TableHeapBuffer buffer)
463
for (int i = 0; i < length; i++) {
464
buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent
465
buffer.WriteRID (rows [i].Col2, Table.Property); // PropertyList
470
sealed class PropertyTable : MetadataTable<PropertyRow> {
472
public override void Write (TableHeapBuffer buffer)
474
for (int i = 0; i < length; i++) {
475
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
476
buffer.WriteString (rows [i].Col2); // Name
477
buffer.WriteBlob (rows [i].Col3); // Type
482
sealed class MethodSemanticsTable : SortedTable<MethodSemanticsRow> {
484
public override void Write (TableHeapBuffer buffer)
486
for (int i = 0; i < length; i++) {
487
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
488
buffer.WriteRID (rows [i].Col2, Table.Method); // Method
489
buffer.WriteCodedRID (rows [i].Col3, CodedIndex.HasSemantics); // Association
493
public override int Compare (MethodSemanticsRow x, MethodSemanticsRow y)
495
return Compare (x.Col3, y.Col3);
499
sealed class MethodImplTable : MetadataTable<MethodImplRow> {
501
public override void Write (TableHeapBuffer buffer)
503
for (int i = 0; i < length; i++) {
504
buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class
505
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MethodDefOrRef); // MethodBody
506
buffer.WriteCodedRID (rows [i].Col3, CodedIndex.MethodDefOrRef); // MethodDeclaration
511
sealed class ModuleRefTable : MetadataTable<uint> {
513
public override void Write (TableHeapBuffer buffer)
515
for (int i = 0; i < length; i++)
516
buffer.WriteString (rows [i]); // Name
520
sealed class TypeSpecTable : MetadataTable<uint> {
522
public override void Write (TableHeapBuffer buffer)
524
for (int i = 0; i < length; i++)
525
buffer.WriteBlob (rows [i]); // Signature
529
sealed class ImplMapTable : SortedTable<ImplMapRow> {
531
public override void Write (TableHeapBuffer buffer)
533
for (int i = 0; i < length; i++) {
534
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
535
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MemberForwarded); // MemberForwarded
536
buffer.WriteString (rows [i].Col3); // ImportName
537
buffer.WriteRID (rows [i].Col4, Table.ModuleRef); // ImportScope
541
public override int Compare (ImplMapRow x, ImplMapRow y)
543
return Compare (x.Col2, y.Col2);
547
sealed class FieldRVATable : SortedTable<FieldRVARow> {
549
internal int position;
551
public override void Write (TableHeapBuffer buffer)
553
position = buffer.position;
554
for (int i = 0; i < length; i++) {
555
buffer.WriteUInt32 (rows [i].Col1); // RVA
556
buffer.WriteRID (rows [i].Col2, Table.Field); // Field
560
public override int Compare (FieldRVARow x, FieldRVARow y)
562
return Compare (x.Col2, y.Col2);
566
sealed class AssemblyTable : OneRowTable<AssemblyRow> {
568
public override void Write (TableHeapBuffer buffer)
570
buffer.WriteUInt32 ((uint) row.Col1); // AssemblyHashAlgorithm
571
buffer.WriteUInt16 (row.Col2); // MajorVersion
572
buffer.WriteUInt16 (row.Col3); // MinorVersion
573
buffer.WriteUInt16 (row.Col4); // Build
574
buffer.WriteUInt16 (row.Col5); // Revision
575
buffer.WriteUInt32 ((uint) row.Col6); // Flags
576
buffer.WriteBlob (row.Col7); // PublicKey
577
buffer.WriteString (row.Col8); // Name
578
buffer.WriteString (row.Col9); // Culture
582
sealed class AssemblyRefTable : MetadataTable<AssemblyRefRow> {
584
public override void Write (TableHeapBuffer buffer)
586
for (int i = 0; i < length; i++) {
587
buffer.WriteUInt16 (rows [i].Col1); // MajorVersion
588
buffer.WriteUInt16 (rows [i].Col2); // MinorVersion
589
buffer.WriteUInt16 (rows [i].Col3); // Build
590
buffer.WriteUInt16 (rows [i].Col4); // Revision
591
buffer.WriteUInt32 ((uint) rows [i].Col5); // Flags
592
buffer.WriteBlob (rows [i].Col6); // PublicKeyOrToken
593
buffer.WriteString (rows [i].Col7); // Name
594
buffer.WriteString (rows [i].Col8); // Culture
595
buffer.WriteBlob (rows [i].Col9); // Hash
600
sealed class FileTable : MetadataTable<FileRow> {
602
public override void Write (TableHeapBuffer buffer)
604
for (int i = 0; i < length; i++) {
605
buffer.WriteUInt32 ((uint) rows [i].Col1);
606
buffer.WriteString (rows [i].Col2);
607
buffer.WriteBlob (rows [i].Col3);
612
sealed class ExportedTypeTable : MetadataTable<ExportedTypeRow> {
614
public override void Write (TableHeapBuffer buffer)
616
for (int i = 0; i < length; i++) {
617
buffer.WriteUInt32 ((uint) rows [i].Col1);
618
buffer.WriteUInt32 (rows [i].Col2);
619
buffer.WriteString (rows [i].Col3);
620
buffer.WriteString (rows [i].Col4);
621
buffer.WriteCodedRID (rows [i].Col5, CodedIndex.Implementation);
626
sealed class ManifestResourceTable : MetadataTable<ManifestResourceRow> {
628
public override void Write (TableHeapBuffer buffer)
630
for (int i = 0; i < length; i++) {
631
buffer.WriteUInt32 (rows [i].Col1);
632
buffer.WriteUInt32 ((uint) rows [i].Col2);
633
buffer.WriteString (rows [i].Col3);
634
buffer.WriteCodedRID (rows [i].Col4, CodedIndex.Implementation);
639
sealed class NestedClassTable : SortedTable<NestedClassRow> {
641
public override void Write (TableHeapBuffer buffer)
643
for (int i = 0; i < length; i++) {
644
buffer.WriteRID (rows [i].Col1, Table.TypeDef); // NestedClass
645
buffer.WriteRID (rows [i].Col2, Table.TypeDef); // EnclosingClass
649
public override int Compare (NestedClassRow x, NestedClassRow y)
651
return Compare (x.Col1, y.Col1);
655
sealed class GenericParamTable : MetadataTable<GenericParamRow> {
657
public override void Write (TableHeapBuffer buffer)
659
for (int i = 0; i < length; i++) {
660
buffer.WriteUInt16 (rows [i].Col1); // Number
661
buffer.WriteUInt16 ((ushort) rows [i].Col2); // Flags
662
buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeOrMethodDef); // Owner
663
buffer.WriteString (rows [i].Col4); // Name
668
sealed class MethodSpecTable : MetadataTable<MethodSpecRow> {
670
public override void Write (TableHeapBuffer buffer)
672
for (int i = 0; i < length; i++) {
673
buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MethodDefOrRef); // Method
674
buffer.WriteBlob (rows [i].Col2); // Instantiation
679
sealed class GenericParamConstraintTable : MetadataTable<GenericParamConstraintRow> {
681
public override void Write (TableHeapBuffer buffer)
683
for (int i = 0; i < length; i++) {
684
buffer.WriteRID (rows [i].Col1, Table.GenericParam); // Owner
685
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Constraint
690
sealed class MetadataBuilder {
692
readonly internal ModuleDefinition module;
693
readonly internal ISymbolWriterProvider symbol_writer_provider;
694
readonly internal ISymbolWriter symbol_writer;
695
readonly internal TextMap text_map;
696
readonly internal string fq_name;
698
readonly Dictionary<TypeRefRow, MetadataToken> type_ref_map;
699
readonly Dictionary<uint, MetadataToken> type_spec_map;
700
readonly Dictionary<MemberRefRow, MetadataToken> member_ref_map;
701
readonly Dictionary<MethodSpecRow, MetadataToken> method_spec_map;
702
readonly Collection<GenericParameter> generic_parameters;
703
readonly Dictionary<MetadataToken, MetadataToken> method_def_map;
705
readonly internal CodeWriter code;
706
readonly internal DataBuffer data;
707
readonly internal ResourceBuffer resources;
708
readonly internal StringHeapBuffer string_heap;
709
readonly internal UserStringHeapBuffer user_string_heap;
710
readonly internal BlobHeapBuffer blob_heap;
711
readonly internal TableHeapBuffer table_heap;
713
internal MetadataToken entry_point;
719
RID property_rid = 1;
722
readonly TypeRefTable type_ref_table;
723
readonly TypeDefTable type_def_table;
724
readonly FieldTable field_table;
725
readonly MethodTable method_table;
726
readonly ParamTable param_table;
727
readonly InterfaceImplTable iface_impl_table;
728
readonly MemberRefTable member_ref_table;
729
readonly ConstantTable constant_table;
730
readonly CustomAttributeTable custom_attribute_table;
731
readonly DeclSecurityTable declsec_table;
732
readonly StandAloneSigTable standalone_sig_table;
733
readonly EventMapTable event_map_table;
734
readonly EventTable event_table;
735
readonly PropertyMapTable property_map_table;
736
readonly PropertyTable property_table;
737
readonly TypeSpecTable typespec_table;
738
readonly MethodSpecTable method_spec_table;
740
readonly internal bool write_symbols;
742
public MetadataBuilder (ModuleDefinition module, string fq_name, ISymbolWriterProvider symbol_writer_provider, ISymbolWriter symbol_writer)
744
this.module = module;
745
this.text_map = CreateTextMap ();
746
this.fq_name = fq_name;
747
this.symbol_writer_provider = symbol_writer_provider;
748
this.symbol_writer = symbol_writer;
749
this.write_symbols = symbol_writer != null;
750
this.code = new CodeWriter (this);
751
this.data = new DataBuffer ();
752
this.resources = new ResourceBuffer ();
753
this.string_heap = new StringHeapBuffer ();
754
this.user_string_heap = new UserStringHeapBuffer ();
755
this.blob_heap = new BlobHeapBuffer ();
756
this.table_heap = new TableHeapBuffer (module, this);
758
this.type_ref_table = GetTable<TypeRefTable> (Table.TypeRef);
759
this.type_def_table = GetTable<TypeDefTable> (Table.TypeDef);
760
this.field_table = GetTable<FieldTable> (Table.Field);
761
this.method_table = GetTable<MethodTable> (Table.Method);
762
this.param_table = GetTable<ParamTable> (Table.Param);
763
this.iface_impl_table = GetTable<InterfaceImplTable> (Table.InterfaceImpl);
764
this.member_ref_table = GetTable<MemberRefTable> (Table.MemberRef);
765
this.constant_table = GetTable<ConstantTable> (Table.Constant);
766
this.custom_attribute_table = GetTable<CustomAttributeTable> (Table.CustomAttribute);
767
this.declsec_table = GetTable<DeclSecurityTable> (Table.DeclSecurity);
768
this.standalone_sig_table = GetTable<StandAloneSigTable> (Table.StandAloneSig);
769
this.event_map_table = GetTable<EventMapTable> (Table.EventMap);
770
this.event_table = GetTable<EventTable> (Table.Event);
771
this.property_map_table = GetTable<PropertyMapTable> (Table.PropertyMap);
772
this.property_table = GetTable<PropertyTable> (Table.Property);
773
this.typespec_table = GetTable<TypeSpecTable> (Table.TypeSpec);
774
this.method_spec_table = GetTable<MethodSpecTable> (Table.MethodSpec);
776
var row_equality_comparer = new RowEqualityComparer ();
777
type_ref_map = new Dictionary<TypeRefRow, MetadataToken> (row_equality_comparer);
778
type_spec_map = new Dictionary<uint, MetadataToken> ();
779
member_ref_map = new Dictionary<MemberRefRow, MetadataToken> (row_equality_comparer);
780
method_spec_map = new Dictionary<MethodSpecRow, MetadataToken> (row_equality_comparer);
781
generic_parameters = new Collection<GenericParameter> ();
783
method_def_map = new Dictionary<MetadataToken, MetadataToken> ();
786
TextMap CreateTextMap ()
788
var map = new TextMap ();
789
map.AddMap (TextSegment.ImportAddressTable, module.Architecture == TargetArchitecture.I386 ? 8 : 16);
790
map.AddMap (TextSegment.CLIHeader, 0x48, 8);
794
TTable GetTable<TTable> (Table table) where TTable : MetadataTable, new ()
796
return table_heap.GetTable<TTable> (table);
799
uint GetStringIndex (string @string)
801
if (string.IsNullOrEmpty (@string))
804
return string_heap.GetStringIndex (@string);
807
uint GetBlobIndex (ByteBuffer blob)
809
if (blob.length == 0)
812
return blob_heap.GetBlobIndex (blob);
815
uint GetBlobIndex (byte [] blob)
817
if (blob.IsNullOrEmpty ())
820
return GetBlobIndex (new ByteBuffer (blob));
823
public void BuildMetadata ()
827
table_heap.WriteTableHeap ();
832
var table = GetTable<ModuleTable> (Table.Module);
833
table.row = GetStringIndex (module.Name);
835
var assembly = module.Assembly;
837
if (assembly != null)
840
if (module.HasAssemblyReferences)
841
AddAssemblyReferences ();
843
if (module.HasModuleReferences)
844
AddModuleReferences ();
846
if (module.HasResources)
849
if (module.HasExportedTypes)
854
if (assembly != null) {
855
if (assembly.HasCustomAttributes)
856
AddCustomAttributes (assembly);
858
if (assembly.HasSecurityDeclarations)
859
AddSecurityDeclarations (assembly);
862
if (module.HasCustomAttributes)
863
AddCustomAttributes (module);
865
if (module.EntryPoint != null)
866
entry_point = LookupToken (module.EntryPoint);
869
void BuildAssembly ()
871
var assembly = module.Assembly;
872
var name = assembly.Name;
874
var table = GetTable<AssemblyTable> (Table.Assembly);
876
table.row = new AssemblyRow (
878
(ushort) name.Version.Major,
879
(ushort) name.Version.Minor,
880
(ushort) name.Version.Build,
881
(ushort) name.Version.Revision,
883
GetBlobIndex (name.PublicKey),
884
GetStringIndex (name.Name),
885
GetStringIndex (name.Culture));
887
if (assembly.Modules.Count > 1)
893
var modules = this.module.Assembly.Modules;
894
var table = GetTable<FileTable> (Table.File);
896
for (int i = 0; i < modules.Count; i++) {
897
var module = modules [i];
901
var parameters = new WriterParameters {
902
SymbolWriterProvider = symbol_writer_provider,
905
var file_name = GetModuleFileName (module.Name);
906
module.Write (file_name, parameters);
908
var hash = CryptoService.ComputeHash (file_name);
910
table.AddRow (new FileRow (
911
FileAttributes.ContainsMetaData,
912
GetStringIndex (module.Name),
913
GetBlobIndex (hash)));
917
string GetModuleFileName (string name)
919
if (string.IsNullOrEmpty (name))
920
throw new NotSupportedException ();
922
var path = Path.GetDirectoryName (fq_name);
923
return Path.Combine (path, name);
926
void AddAssemblyReferences ()
928
var references = module.AssemblyReferences;
929
var table = GetTable<AssemblyRefTable> (Table.AssemblyRef);
931
for (int i = 0; i < references.Count; i++) {
932
var reference = references [i];
934
var key_or_token = reference.PublicKey.IsNullOrEmpty ()
935
? reference.PublicKeyToken
936
: reference.PublicKey;
938
var rid = table.AddRow (new AssemblyRefRow (
939
(ushort) reference.Version.Major,
940
(ushort) reference.Version.Minor,
941
(ushort) reference.Version.Build,
942
(ushort) reference.Version.Revision,
943
reference.Attributes,
944
GetBlobIndex (key_or_token),
945
GetStringIndex (reference.Name),
946
GetStringIndex (reference.Culture),
947
GetBlobIndex (reference.Hash)));
949
reference.token = new MetadataToken (TokenType.AssemblyRef, rid);
953
void AddModuleReferences ()
955
var references = module.ModuleReferences;
956
var table = GetTable<ModuleRefTable> (Table.ModuleRef);
958
for (int i = 0; i < references.Count; i++) {
959
var reference = references [i];
961
reference.token = new MetadataToken (
963
table.AddRow (GetStringIndex (reference.Name)));
969
var resources = module.Resources;
970
var table = GetTable<ManifestResourceTable> (Table.ManifestResource);
972
for (int i = 0; i < resources.Count; i++) {
973
var resource = resources [i];
975
var row = new ManifestResourceRow (
978
GetStringIndex (resource.Name),
981
switch (resource.ResourceType) {
982
case ResourceType.Embedded:
983
row.Col1 = AddEmbeddedResource ((EmbeddedResource) resource);
985
case ResourceType.Linked:
986
row.Col4 = CodedIndex.Implementation.CompressMetadataToken (
989
AddLinkedResource ((LinkedResource) resource)));
991
case ResourceType.AssemblyLinked:
992
row.Col4 = CodedIndex.Implementation.CompressMetadataToken (
993
((AssemblyLinkedResource) resource).Assembly.MetadataToken);
996
throw new NotSupportedException ();
1003
uint AddLinkedResource (LinkedResource resource)
1005
var table = GetTable<FileTable> (Table.File);
1007
var hash = resource.Hash.IsNullOrEmpty ()
1008
? CryptoService.ComputeHash (resource.File)
1011
return (uint) table.AddRow (new FileRow (
1012
FileAttributes.ContainsNoMetaData,
1013
GetStringIndex (resource.File),
1014
GetBlobIndex (hash)));
1017
uint AddEmbeddedResource (EmbeddedResource resource)
1019
return resources.AddResource (resource.GetResourceData ());
1022
void AddExportedTypes ()
1024
var exported_types = module.ExportedTypes;
1025
var table = GetTable<ExportedTypeTable> (Table.ExportedType);
1027
for (int i = 0; i < exported_types.Count; i++) {
1028
var exported_type = exported_types [i];
1030
var rid = table.AddRow (new ExportedTypeRow (
1031
exported_type.Attributes,
1032
(uint) exported_type.Identifier,
1033
GetStringIndex (exported_type.Name),
1034
GetStringIndex (exported_type.Namespace),
1035
MakeCodedRID (GetExportedTypeScope (exported_type), CodedIndex.Implementation)));
1037
exported_type.token = new MetadataToken (TokenType.ExportedType, rid);
1041
MetadataToken GetExportedTypeScope (ExportedType exported_type)
1043
if (exported_type.DeclaringType != null)
1044
return exported_type.DeclaringType.MetadataToken;
1046
var scope = exported_type.Scope;
1047
switch (scope.MetadataToken.TokenType) {
1048
case TokenType.AssemblyRef:
1049
return scope.MetadataToken;
1050
case TokenType.ModuleRef:
1051
var file_table = GetTable<FileTable> (Table.File);
1052
for (int i = 0; i < file_table.length; i++)
1053
if (file_table.rows [i].Col2 == GetStringIndex (scope.Name))
1054
return new MetadataToken (TokenType.File, i + 1);
1059
throw new NotSupportedException ();
1064
if (!module.HasTypes)
1069
AddGenericParameters ();
1072
void AttachTokens ()
1074
var types = module.Types;
1076
for (int i = 0; i < types.Count; i++)
1077
AttachTypeDefToken (types [i]);
1080
void AttachTypeDefToken (TypeDefinition type)
1082
type.token = new MetadataToken (TokenType.TypeDef, type_rid++);
1083
type.fields_range.Start = field_rid;
1084
type.methods_range.Start = method_rid;
1087
AttachFieldsDefToken (type);
1089
if (type.HasMethods)
1090
AttachMethodsDefToken (type);
1092
if (type.HasNestedTypes)
1093
AttachNestedTypesDefToken (type);
1096
void AttachNestedTypesDefToken (TypeDefinition type)
1098
var nested_types = type.NestedTypes;
1099
for (int i = 0; i < nested_types.Count; i++)
1100
AttachTypeDefToken (nested_types [i]);
1103
void AttachFieldsDefToken (TypeDefinition type)
1105
var fields = type.Fields;
1106
type.fields_range.Length = (uint) fields.Count;
1107
for (int i = 0; i < fields.Count; i++)
1108
fields [i].token = new MetadataToken (TokenType.Field, field_rid++);
1111
void AttachMethodsDefToken (TypeDefinition type)
1113
var methods = type.Methods;
1114
type.methods_range.Length = (uint) methods.Count;
1115
for (int i = 0; i < methods.Count; i++) {
1116
var method = methods [i];
1117
var new_token = new MetadataToken (TokenType.Method, method_rid++);
1119
if (write_symbols && method.token != MetadataToken.Zero)
1120
method_def_map.Add (new_token, method.token);
1122
method.token = new_token;
1126
public bool TryGetOriginalMethodToken (MetadataToken new_token, out MetadataToken original)
1128
return method_def_map.TryGetValue (new_token, out original);
1131
MetadataToken GetTypeToken (TypeReference type)
1134
return MetadataToken.Zero;
1136
if (type.IsDefinition)
1139
if (type.IsTypeSpecification ())
1140
return GetTypeSpecToken (type);
1142
return GetTypeRefToken (type);
1145
MetadataToken GetTypeSpecToken (TypeReference type)
1147
var row = GetBlobIndex (GetTypeSpecSignature (type));
1149
MetadataToken token;
1150
if (type_spec_map.TryGetValue (row, out token))
1153
return AddTypeSpecification (type, row);
1156
MetadataToken AddTypeSpecification (TypeReference type, uint row)
1158
type.token = new MetadataToken (TokenType.TypeSpec, typespec_table.AddRow (row));
1160
var token = type.token;
1161
type_spec_map.Add (row, token);
1165
MetadataToken GetTypeRefToken (TypeReference type)
1167
var row = CreateTypeRefRow (type);
1169
MetadataToken token;
1170
if (type_ref_map.TryGetValue (row, out token))
1173
return AddTypeReference (type, row);
1176
TypeRefRow CreateTypeRefRow (TypeReference type)
1178
var scope_token = type.IsNested
1179
? GetTypeRefToken (type.DeclaringType)
1180
: type.Scope.MetadataToken;
1182
return new TypeRefRow (
1183
MakeCodedRID (scope_token, CodedIndex.ResolutionScope),
1184
GetStringIndex (type.Name),
1185
GetStringIndex (type.Namespace));
1188
static CodedRID MakeCodedRID (IMetadataTokenProvider provider, CodedIndex index)
1190
return MakeCodedRID (provider.MetadataToken, index);
1193
static CodedRID MakeCodedRID (MetadataToken token, CodedIndex index)
1195
return index.CompressMetadataToken (token);
1198
MetadataToken AddTypeReference (TypeReference type, TypeRefRow row)
1200
type.token = new MetadataToken (TokenType.TypeRef, type_ref_table.AddRow (row));
1202
var token = type.token;
1203
type_ref_map.Add (row, token);
1209
var types = module.Types;
1211
for (int i = 0; i < types.Count; i++)
1212
AddType (types [i]);
1215
void AddType (TypeDefinition type)
1217
type_def_table.AddRow (new TypeDefRow (
1219
GetStringIndex (type.Name),
1220
GetStringIndex (type.Namespace),
1221
MakeCodedRID (GetTypeToken (type.BaseType), CodedIndex.TypeDefOrRef),
1222
type.fields_range.Start,
1223
type.methods_range.Start));
1225
if (type.HasGenericParameters)
1226
AddGenericParameters (type);
1228
if (type.HasInterfaces)
1229
AddInterfaces (type);
1231
if (type.HasLayoutInfo)
1232
AddLayoutInfo (type);
1237
if (type.HasMethods)
1240
if (type.HasProperties)
1241
AddProperties (type);
1246
if (type.HasCustomAttributes)
1247
AddCustomAttributes (type);
1249
if (type.HasSecurityDeclarations)
1250
AddSecurityDeclarations (type);
1252
if (type.HasNestedTypes)
1253
AddNestedTypes (type);
1256
void AddGenericParameters (IGenericParameterProvider owner)
1258
var parameters = owner.GenericParameters;
1260
for (int i = 0; i < parameters.Count; i++)
1261
generic_parameters.Add (parameters [i]);
1264
sealed class GenericParameterComparer : IComparer<GenericParameter> {
1266
public int Compare (GenericParameter a, GenericParameter b)
1268
var a_owner = MakeCodedRID (a.Owner, CodedIndex.TypeOrMethodDef);
1269
var b_owner = MakeCodedRID (b.Owner, CodedIndex.TypeOrMethodDef);
1270
if (a_owner == b_owner) {
1271
var a_pos = a.Position;
1272
var b_pos = b.Position;
1273
return a_pos == b_pos ? 0 : a_pos > b_pos ? 1 : -1;
1276
return a_owner > b_owner ? 1 : -1;
1280
void AddGenericParameters ()
1282
var items = this.generic_parameters.items;
1283
var size = this.generic_parameters.size;
1284
Array.Sort (items, 0, size, new GenericParameterComparer ());
1286
var generic_param_table = GetTable<GenericParamTable> (Table.GenericParam);
1287
var generic_param_constraint_table = GetTable<GenericParamConstraintTable> (Table.GenericParamConstraint);
1289
for (int i = 0; i < size; i++) {
1290
var generic_parameter = items [i];
1292
var rid = generic_param_table.AddRow (new GenericParamRow (
1293
(ushort) generic_parameter.Position,
1294
generic_parameter.Attributes,
1295
MakeCodedRID (generic_parameter.Owner, CodedIndex.TypeOrMethodDef),
1296
GetStringIndex (generic_parameter.Name)));
1298
generic_parameter.token = new MetadataToken (TokenType.GenericParam, rid);
1300
if (generic_parameter.HasConstraints)
1301
AddConstraints (generic_parameter, generic_param_constraint_table);
1303
if (generic_parameter.HasCustomAttributes)
1304
AddCustomAttributes (generic_parameter);
1308
void AddConstraints (GenericParameter generic_parameter, GenericParamConstraintTable table)
1310
var constraints = generic_parameter.Constraints;
1312
var rid = generic_parameter.token.RID;
1314
for (int i = 0; i < constraints.Count; i++)
1315
table.AddRow (new GenericParamConstraintRow (
1317
MakeCodedRID (GetTypeToken (constraints [i]), CodedIndex.TypeDefOrRef)));
1320
void AddInterfaces (TypeDefinition type)
1322
var interfaces = type.Interfaces;
1323
var type_rid = type.token.RID;
1325
for (int i = 0; i < interfaces.Count; i++)
1326
iface_impl_table.AddRow (new InterfaceImplRow (
1328
MakeCodedRID (GetTypeToken (interfaces [i]), CodedIndex.TypeDefOrRef)));
1331
void AddLayoutInfo (TypeDefinition type)
1333
var table = GetTable<ClassLayoutTable> (Table.ClassLayout);
1335
table.AddRow (new ClassLayoutRow (
1336
(ushort) type.PackingSize,
1337
(uint) type.ClassSize,
1341
void AddNestedTypes (TypeDefinition type)
1343
var nested_types = type.NestedTypes;
1344
var nested_table = GetTable<NestedClassTable> (Table.NestedClass);
1346
for (int i = 0; i < nested_types.Count; i++) {
1347
var nested = nested_types [i];
1349
nested_table.AddRow (new NestedClassRow (nested.token.RID, type.token.RID));
1353
void AddFields (TypeDefinition type)
1355
var fields = type.Fields;
1357
for (int i = 0; i < fields.Count; i++)
1358
AddField (fields [i]);
1361
void AddField (FieldDefinition field)
1363
field_table.AddRow (new FieldRow (
1365
GetStringIndex (field.Name),
1366
GetBlobIndex (GetFieldSignature (field))));
1368
if (!field.InitialValue.IsNullOrEmpty ())
1369
AddFieldRVA (field);
1371
if (field.HasLayoutInfo)
1372
AddFieldLayout (field);
1374
if (field.HasCustomAttributes)
1375
AddCustomAttributes (field);
1377
if (field.HasConstant)
1378
AddConstant (field, field.FieldType);
1380
if (field.HasMarshalInfo)
1381
AddMarshalInfo (field);
1384
void AddFieldRVA (FieldDefinition field)
1386
var table = GetTable<FieldRVATable> (Table.FieldRVA);
1387
table.AddRow (new FieldRVARow (
1388
data.AddData (field.InitialValue),
1392
void AddFieldLayout (FieldDefinition field)
1394
var table = GetTable<FieldLayoutTable> (Table.FieldLayout);
1395
table.AddRow (new FieldLayoutRow ((uint) field.Offset, field.token.RID));
1398
void AddMethods (TypeDefinition type)
1400
var methods = type.Methods;
1402
for (int i = 0; i < methods.Count; i++)
1403
AddMethod (methods [i]);
1406
void AddMethod (MethodDefinition method)
1408
method_table.AddRow (new MethodRow (
1409
method.HasBody ? code.WriteMethodBody (method) : 0,
1410
method.ImplAttributes,
1412
GetStringIndex (method.Name),
1413
GetBlobIndex (GetMethodSignature (method)),
1416
AddParameters (method);
1418
if (method.HasGenericParameters)
1419
AddGenericParameters (method);
1421
if (method.IsPInvokeImpl)
1422
AddPInvokeInfo (method);
1424
if (method.HasCustomAttributes)
1425
AddCustomAttributes (method);
1427
if (method.HasSecurityDeclarations)
1428
AddSecurityDeclarations (method);
1430
if (method.HasOverrides)
1431
AddOverrides (method);
1434
void AddParameters (MethodDefinition method)
1436
var return_parameter = method.MethodReturnType.parameter;
1438
if (return_parameter != null && RequiresParameterRow (return_parameter))
1439
AddParameter (0, return_parameter, param_table);
1441
if (!method.HasParameters)
1444
var parameters = method.Parameters;
1446
for (int i = 0; i < parameters.Count; i++) {
1447
var parameter = parameters [i];
1448
if (!RequiresParameterRow (parameter))
1451
AddParameter ((ushort) (i + 1), parameter, param_table);
1455
void AddPInvokeInfo (MethodDefinition method)
1457
var pinvoke = method.PInvokeInfo;
1458
if (pinvoke == null)
1459
throw new ArgumentException ();
1461
var table = GetTable<ImplMapTable> (Table.ImplMap);
1462
table.AddRow (new ImplMapRow (
1464
MakeCodedRID (method, CodedIndex.MemberForwarded),
1465
GetStringIndex (pinvoke.EntryPoint),
1466
pinvoke.Module.MetadataToken.RID));
1469
void AddOverrides (MethodDefinition method)
1471
var overrides = method.Overrides;
1472
var table = GetTable<MethodImplTable> (Table.MethodImpl);
1474
for (int i = 0; i < overrides.Count; i++) {
1475
table.AddRow (new MethodImplRow (
1476
method.DeclaringType.token.RID,
1477
MakeCodedRID (method, CodedIndex.MethodDefOrRef),
1478
MakeCodedRID (LookupToken (overrides [i]), CodedIndex.MethodDefOrRef)));
1482
static bool RequiresParameterRow (ParameterDefinition parameter)
1484
return !string.IsNullOrEmpty (parameter.Name)
1485
|| parameter.Attributes != ParameterAttributes.None
1486
|| parameter.HasMarshalInfo
1487
|| parameter.HasConstant
1488
|| parameter.HasCustomAttributes;
1491
void AddParameter (ushort sequence, ParameterDefinition parameter, ParamTable table)
1493
table.AddRow (new ParamRow (
1494
parameter.Attributes,
1496
GetStringIndex (parameter.Name)));
1498
parameter.token = new MetadataToken (TokenType.Param, param_rid++);
1500
if (parameter.HasCustomAttributes)
1501
AddCustomAttributes (parameter);
1503
if (parameter.HasConstant)
1504
AddConstant (parameter, parameter.ParameterType);
1506
if (parameter.HasMarshalInfo)
1507
AddMarshalInfo (parameter);
1510
void AddMarshalInfo (IMarshalInfoProvider owner)
1512
var table = GetTable<FieldMarshalTable> (Table.FieldMarshal);
1514
table.AddRow (new FieldMarshalRow (
1515
MakeCodedRID (owner, CodedIndex.HasFieldMarshal),
1516
GetBlobIndex (GetMarshalInfoSignature (owner))));
1519
void AddProperties (TypeDefinition type)
1521
var properties = type.Properties;
1523
property_map_table.AddRow (new PropertyMapRow (type.token.RID, property_rid));
1525
for (int i = 0; i < properties.Count; i++)
1526
AddProperty (properties [i]);
1529
void AddProperty (PropertyDefinition property)
1531
property_table.AddRow (new PropertyRow (
1532
property.Attributes,
1533
GetStringIndex (property.Name),
1534
GetBlobIndex (GetPropertySignature (property))));
1535
property.token = new MetadataToken (TokenType.Property, property_rid++);
1537
var method = property.GetMethod;
1539
AddSemantic (MethodSemanticsAttributes.Getter, property, method);
1541
method = property.SetMethod;
1543
AddSemantic (MethodSemanticsAttributes.Setter, property, method);
1545
if (property.HasOtherMethods)
1546
AddOtherSemantic (property, property.OtherMethods);
1548
if (property.HasCustomAttributes)
1549
AddCustomAttributes (property);
1551
if (property.HasConstant)
1552
AddConstant (property, property.PropertyType);
1555
void AddOtherSemantic (IMetadataTokenProvider owner, Collection<MethodDefinition> others)
1557
for (int i = 0; i < others.Count; i++)
1558
AddSemantic (MethodSemanticsAttributes.Other, owner, others [i]);
1561
void AddEvents (TypeDefinition type)
1563
var events = type.Events;
1565
event_map_table.AddRow (new EventMapRow (type.token.RID, event_rid));
1567
for (int i = 0; i < events.Count; i++)
1568
AddEvent (events [i]);
1571
void AddEvent (EventDefinition @event)
1573
event_table.AddRow (new EventRow (
1575
GetStringIndex (@event.Name),
1576
MakeCodedRID (GetTypeToken (@event.EventType), CodedIndex.TypeDefOrRef)));
1577
@event.token = new MetadataToken (TokenType.Event, event_rid++);
1579
var method = @event.AddMethod;
1581
AddSemantic (MethodSemanticsAttributes.AddOn, @event, method);
1583
method = @event.InvokeMethod;
1585
AddSemantic (MethodSemanticsAttributes.Fire, @event, method);
1587
method = @event.RemoveMethod;
1589
AddSemantic (MethodSemanticsAttributes.RemoveOn, @event, method);
1591
if (@event.HasOtherMethods)
1592
AddOtherSemantic (@event, @event.OtherMethods);
1594
if (@event.HasCustomAttributes)
1595
AddCustomAttributes (@event);
1598
void AddSemantic (MethodSemanticsAttributes semantics, IMetadataTokenProvider provider, MethodDefinition method)
1600
method.SemanticsAttributes = semantics;
1601
var table = GetTable<MethodSemanticsTable> (Table.MethodSemantics);
1603
table.AddRow (new MethodSemanticsRow (
1606
MakeCodedRID (provider, CodedIndex.HasSemantics)));
1609
void AddConstant (IConstantProvider owner, TypeReference type)
1611
var constant = owner.Constant;
1612
var etype = GetConstantType (type, constant);
1614
constant_table.AddRow (new ConstantRow (
1616
MakeCodedRID (owner.MetadataToken, CodedIndex.HasConstant),
1617
GetBlobIndex (GetConstantSignature (etype, constant))));
1620
static ElementType GetConstantType (TypeReference constant_type, object constant)
1622
if (constant == null)
1623
return ElementType.Class;
1625
var etype = constant_type.etype;
1627
case ElementType.None:
1628
var type = constant_type.CheckedResolve ();
1630
return GetConstantType (type.GetEnumUnderlyingType (), constant);
1632
return ElementType.Class;
1633
case ElementType.String:
1634
return ElementType.String;
1635
case ElementType.Object:
1636
return GetConstantType (constant.GetType ());
1637
case ElementType.Array:
1638
case ElementType.SzArray:
1639
case ElementType.MVar:
1640
case ElementType.Var:
1641
return ElementType.Class;
1642
case ElementType.GenericInst:
1643
case ElementType.CModOpt:
1644
case ElementType.CModReqD:
1645
case ElementType.ByRef:
1646
case ElementType.Sentinel:
1647
return GetConstantType (((TypeSpecification) constant_type).ElementType, constant);
1648
case ElementType.Boolean:
1649
case ElementType.Char:
1651
case ElementType.I1:
1652
case ElementType.I2:
1653
case ElementType.I4:
1654
case ElementType.I8:
1656
case ElementType.U1:
1657
case ElementType.U2:
1658
case ElementType.U4:
1659
case ElementType.U8:
1660
case ElementType.R4:
1661
case ElementType.R8:
1662
return GetConstantType (constant.GetType ());
1668
static ElementType GetConstantType (Type type)
1670
switch (Type.GetTypeCode (type)) {
1671
case TypeCode.Boolean:
1672
return ElementType.Boolean;
1674
return ElementType.U1;
1675
case TypeCode.SByte:
1676
return ElementType.I1;
1678
return ElementType.Char;
1679
case TypeCode.Int16:
1680
return ElementType.I2;
1681
case TypeCode.UInt16:
1682
return ElementType.U2;
1683
case TypeCode.Int32:
1684
return ElementType.I4;
1685
case TypeCode.UInt32:
1686
return ElementType.U4;
1687
case TypeCode.Int64:
1688
return ElementType.I8;
1689
case TypeCode.UInt64:
1690
return ElementType.U8;
1691
case TypeCode.Single:
1692
return ElementType.R4;
1693
case TypeCode.Double:
1694
return ElementType.R8;
1695
case TypeCode.String:
1696
return ElementType.String;
1698
throw new NotSupportedException (type.FullName);
1702
void AddCustomAttributes (ICustomAttributeProvider owner)
1704
var custom_attributes = owner.CustomAttributes;
1706
for (int i = 0; i < custom_attributes.Count; i++) {
1707
var attribute = custom_attributes [i];
1709
custom_attribute_table.AddRow (new CustomAttributeRow (
1710
MakeCodedRID (owner, CodedIndex.HasCustomAttribute),
1711
MakeCodedRID (LookupToken (attribute.Constructor), CodedIndex.CustomAttributeType),
1712
GetBlobIndex (GetCustomAttributeSignature (attribute))));
1716
void AddSecurityDeclarations (ISecurityDeclarationProvider owner)
1718
var declarations = owner.SecurityDeclarations;
1720
for (int i = 0; i < declarations.Count; i++) {
1721
var declaration = declarations [i];
1723
declsec_table.AddRow (new DeclSecurityRow (
1725
MakeCodedRID (owner, CodedIndex.HasDeclSecurity),
1726
GetBlobIndex (GetSecurityDeclarationSignature (declaration))));
1730
MetadataToken GetMemberRefToken (MemberReference member)
1732
var row = CreateMemberRefRow (member);
1734
MetadataToken token;
1735
if (member_ref_map.TryGetValue (row, out token))
1738
AddMemberReference (member, row);
1740
return member.token;
1743
MemberRefRow CreateMemberRefRow (MemberReference member)
1745
return new MemberRefRow (
1746
MakeCodedRID (GetTypeToken (member.DeclaringType), CodedIndex.MemberRefParent),
1747
GetStringIndex (member.Name),
1748
GetBlobIndex (GetMemberRefSignature (member)));
1751
void AddMemberReference (MemberReference member, MemberRefRow row)
1753
member.token = new MetadataToken (TokenType.MemberRef, member_ref_table.AddRow (row));
1754
member_ref_map.Add (row, member.token);
1757
MetadataToken GetMethodSpecToken (MethodSpecification method_spec)
1759
var row = CreateMethodSpecRow (method_spec);
1761
MetadataToken token;
1762
if (method_spec_map.TryGetValue (row, out token))
1765
AddMethodSpecification (method_spec, row);
1767
return method_spec.token;
1770
void AddMethodSpecification (MethodSpecification method_spec, MethodSpecRow row)
1772
method_spec.token = new MetadataToken (TokenType.MethodSpec, method_spec_table.AddRow (row));
1773
method_spec_map.Add (row, method_spec.token);
1776
MethodSpecRow CreateMethodSpecRow (MethodSpecification method_spec)
1778
return new MethodSpecRow (
1779
MakeCodedRID (LookupToken (method_spec.ElementMethod), CodedIndex.MethodDefOrRef),
1780
GetBlobIndex (GetMethodSpecSignature (method_spec)));
1783
SignatureWriter CreateSignatureWriter ()
1785
return new SignatureWriter (this);
1788
SignatureWriter GetMethodSpecSignature (MethodSpecification method_spec)
1790
if (!method_spec.IsGenericInstance)
1791
throw new NotSupportedException ();
1793
var generic_instance = (GenericInstanceMethod) method_spec;
1795
var signature = CreateSignatureWriter ();
1796
signature.WriteByte (0x0a);
1798
signature.WriteGenericInstanceSignature (generic_instance);
1803
public uint AddStandAloneSignature (uint signature)
1805
return (uint) standalone_sig_table.AddRow (signature);
1808
public uint GetLocalVariableBlobIndex (Collection<VariableDefinition> variables)
1810
return GetBlobIndex (GetVariablesSignature (variables));
1813
public uint GetCallSiteBlobIndex (CallSite call_site)
1815
return GetBlobIndex (GetMethodSignature (call_site));
1818
SignatureWriter GetVariablesSignature (Collection<VariableDefinition> variables)
1820
var signature = CreateSignatureWriter ();
1821
signature.WriteByte (0x7);
1822
signature.WriteCompressedUInt32 ((uint) variables.Count);
1823
for (int i = 0; i < variables.Count; i++)
1824
signature.WriteTypeSignature (variables [i].VariableType);
1828
SignatureWriter GetFieldSignature (FieldReference field)
1830
var signature = CreateSignatureWriter ();
1831
signature.WriteByte (0x6);
1832
signature.WriteTypeSignature (field.FieldType);
1836
SignatureWriter GetMethodSignature (IMethodSignature method)
1838
var signature = CreateSignatureWriter ();
1839
signature.WriteMethodSignature (method);
1843
SignatureWriter GetMemberRefSignature (MemberReference member)
1845
var field = member as FieldReference;
1847
return GetFieldSignature (field);
1849
var method = member as MethodReference;
1851
return GetMethodSignature (method);
1853
throw new NotSupportedException ();
1856
SignatureWriter GetPropertySignature (PropertyDefinition property)
1858
var signature = CreateSignatureWriter ();
1859
byte calling_convention = 0x8;
1860
if (property.HasThis)
1861
calling_convention |= 0x20;
1863
uint param_count = 0;
1864
Collection<ParameterDefinition> parameters = null;
1866
if (property.HasParameters) {
1867
parameters = property.Parameters;
1868
param_count = (uint) parameters.Count;
1871
signature.WriteByte (calling_convention);
1872
signature.WriteCompressedUInt32 (param_count);
1873
signature.WriteTypeSignature (property.PropertyType);
1875
if (param_count == 0)
1878
for (int i = 0; i < param_count; i++)
1879
signature.WriteTypeSignature (parameters [i].ParameterType);
1884
SignatureWriter GetTypeSpecSignature (TypeReference type)
1886
var signature = CreateSignatureWriter ();
1887
signature.WriteTypeSignature (type);
1891
SignatureWriter GetConstantSignature (ElementType type, object value)
1893
var signature = CreateSignatureWriter ();
1896
case ElementType.Array:
1897
case ElementType.SzArray:
1898
case ElementType.Class:
1899
case ElementType.Object:
1900
case ElementType.Var:
1901
case ElementType.MVar:
1902
signature.WriteInt32 (0);
1904
case ElementType.String:
1905
signature.WriteConstantString ((string) value);
1908
signature.WriteConstantPrimitive (value);
1915
SignatureWriter GetCustomAttributeSignature (CustomAttribute attribute)
1917
var signature = CreateSignatureWriter ();
1918
if (!attribute.resolved) {
1919
signature.WriteBytes (attribute.GetBlob ());
1923
signature.WriteUInt16 (0x0001);
1925
signature.WriteCustomAttributeConstructorArguments (attribute);
1927
signature.WriteCustomAttributeNamedArguments (attribute);
1932
SignatureWriter GetSecurityDeclarationSignature (SecurityDeclaration declaration)
1934
var signature = CreateSignatureWriter ();
1935
if (!declaration.resolved) {
1936
signature.WriteBytes (declaration.GetBlob ());
1940
signature.WriteByte ((byte) '.');
1942
var attributes = declaration.security_attributes;
1943
if (attributes == null)
1944
throw new NotSupportedException ();
1946
signature.WriteCompressedUInt32 ((uint) attributes.Count);
1948
for (int i = 0; i < attributes.Count; i++)
1949
signature.WriteSecurityAttribute (attributes [i]);
1954
SignatureWriter GetMarshalInfoSignature (IMarshalInfoProvider owner)
1956
var signature = CreateSignatureWriter ();
1958
signature.WriteMarshalInfo (owner.MarshalInfo);
1963
static Exception CreateForeignMemberException (MemberReference member)
1965
return new ArgumentException (string.Format ("Member '{0}' is declared in another module and needs to be imported", member));
1968
public MetadataToken LookupToken (IMetadataTokenProvider provider)
1970
if (provider == null)
1971
throw new ArgumentNullException ();
1973
var member = provider as MemberReference;
1974
if (member == null || member.Module != module)
1975
throw CreateForeignMemberException (member);
1977
var token = provider.MetadataToken;
1979
switch (token.TokenType) {
1980
case TokenType.TypeDef:
1981
case TokenType.Method:
1982
case TokenType.Field:
1983
case TokenType.Event:
1984
case TokenType.Property:
1986
case TokenType.TypeRef:
1987
case TokenType.TypeSpec:
1988
case TokenType.GenericParam:
1989
return GetTypeToken ((TypeReference) provider);
1990
case TokenType.MethodSpec:
1991
return GetMethodSpecToken ((MethodSpecification) provider);
1992
case TokenType.MemberRef:
1993
return GetMemberRefToken (member);
1995
throw new NotSupportedException ();
2000
sealed class SignatureWriter : ByteBuffer {
2002
readonly MetadataBuilder metadata;
2004
public SignatureWriter (MetadataBuilder metadata)
2007
this.metadata = metadata;
2010
public void WriteElementType (ElementType element_type)
2012
WriteByte ((byte) element_type);
2015
public void WriteUTF8String (string @string)
2017
if (@string == null) {
2022
var bytes = Encoding.UTF8.GetBytes (@string);
2023
WriteCompressedUInt32 ((uint) bytes.Length);
2027
public void WriteMethodSignature (IMethodSignature method)
2029
byte calling_convention = (byte) method.CallingConvention;
2031
calling_convention |= 0x20;
2032
if (method.ExplicitThis)
2033
calling_convention |= 0x40;
2035
var generic_provider = method as IGenericParameterProvider;
2036
var generic_arity = generic_provider != null && generic_provider.HasGenericParameters
2037
? generic_provider.GenericParameters.Count
2040
if (generic_arity > 0)
2041
calling_convention |= 0x10;
2043
var param_count = method.HasParameters ? method.Parameters.Count : 0;
2045
WriteByte (calling_convention);
2047
if (generic_arity > 0)
2048
WriteCompressedUInt32 ((uint) generic_arity);
2050
WriteCompressedUInt32 ((uint) param_count);
2051
WriteTypeSignature (method.ReturnType);
2053
if (param_count == 0)
2056
var parameters = method.Parameters;
2058
for (int i = 0; i < param_count; i++)
2059
WriteTypeSignature (parameters [i].ParameterType);
2062
uint MakeTypeDefOrRefCodedRID (TypeReference type)
2064
return CodedIndex.TypeDefOrRef.CompressMetadataToken (metadata.LookupToken (type));
2067
public void WriteTypeSignature (TypeReference type)
2070
throw new ArgumentNullException ();
2072
var etype = type.etype;
2075
case ElementType.MVar:
2076
case ElementType.Var: {
2077
var generic_parameter = (GenericParameter) type;
2079
WriteElementType (etype);
2080
var position = generic_parameter.Position;
2082
throw new NotSupportedException ();
2084
WriteCompressedUInt32 ((uint) position);
2088
case ElementType.GenericInst: {
2089
var generic_instance = (GenericInstanceType) type;
2090
WriteElementType (ElementType.GenericInst);
2091
WriteElementType (generic_instance.IsValueType ? ElementType.ValueType : ElementType.Class);
2092
WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (generic_instance.ElementType));
2094
WriteGenericInstanceSignature (generic_instance);
2098
case ElementType.Ptr:
2099
case ElementType.ByRef:
2100
case ElementType.Pinned:
2101
case ElementType.Sentinel: {
2102
var type_spec = (TypeSpecification) type;
2103
WriteElementType (etype);
2104
WriteTypeSignature (type_spec.ElementType);
2108
case ElementType.FnPtr: {
2109
var fptr = (FunctionPointerType) type;
2110
WriteElementType (ElementType.FnPtr);
2111
WriteMethodSignature (fptr);
2115
case ElementType.CModOpt:
2116
case ElementType.CModReqD: {
2117
var modifier = (IModifierType) type;
2118
WriteModifierSignature (etype, modifier);
2122
case ElementType.Array: {
2123
var array = (ArrayType) type;
2124
if (!array.IsVector) {
2125
WriteArrayTypeSignature (array);
2129
WriteElementType (ElementType.SzArray);
2130
WriteTypeSignature (array.ElementType);
2134
case ElementType.None: {
2135
WriteElementType (type.IsValueType ? ElementType.ValueType : ElementType.Class);
2136
WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type));
2141
if (!TryWriteElementType (type))
2142
throw new NotSupportedException ();
2149
void WriteArrayTypeSignature (ArrayType array)
2151
WriteElementType (ElementType.Array);
2152
WriteTypeSignature (array.ElementType);
2154
var dimensions = array.Dimensions;
2155
var rank = dimensions.Count;
2157
WriteCompressedUInt32 ((uint) rank);
2162
for (int i = 0; i < rank; i++) {
2163
var dimension = dimensions [i];
2165
if (dimension.UpperBound.HasValue) {
2168
} else if (dimension.LowerBound.HasValue)
2172
var sizes = new int [sized];
2173
var low_bounds = new int [lbounds];
2175
for (int i = 0; i < lbounds; i++) {
2176
var dimension = dimensions [i];
2177
low_bounds [i] = dimension.LowerBound.GetValueOrDefault ();
2178
if (dimension.UpperBound.HasValue)
2179
sizes [i] = dimension.UpperBound.Value - low_bounds [i] + 1;
2182
WriteCompressedUInt32 ((uint) sized);
2183
for (int i = 0; i < sized; i++)
2184
WriteCompressedUInt32 ((uint) sizes [i]);
2186
WriteCompressedUInt32 ((uint) lbounds);
2187
for (int i = 0; i < lbounds; i++)
2188
WriteCompressedInt32 (low_bounds [i]);
2191
public void WriteGenericInstanceSignature (IGenericInstance instance)
2193
var generic_arguments = instance.GenericArguments;
2194
var arity = generic_arguments.Count;
2196
WriteCompressedUInt32 ((uint) arity);
2197
for (int i = 0; i < arity; i++)
2198
WriteTypeSignature (generic_arguments [i]);
2201
void WriteModifierSignature (ElementType element_type, IModifierType type)
2203
WriteElementType (element_type);
2204
WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type.ModifierType));
2205
WriteTypeSignature (type.ElementType);
2208
bool TryWriteElementType (TypeReference type)
2210
var element = type.etype;
2212
if (element == ElementType.None)
2215
WriteElementType (element);
2219
public void WriteConstantString (string value)
2221
WriteBytes (Encoding.Unicode.GetBytes (value));
2224
public void WriteConstantPrimitive (object value)
2226
WritePrimitiveValue (value);
2229
public void WriteCustomAttributeConstructorArguments (CustomAttribute attribute)
2231
if (!attribute.HasConstructorArguments)
2234
var arguments = attribute.ConstructorArguments;
2235
var parameters = attribute.Constructor.Parameters;
2237
if (parameters.Count != arguments.Count)
2238
throw new InvalidOperationException ();
2240
for (int i = 0; i < arguments.Count; i++)
2241
WriteCustomAttributeFixedArgument (parameters [i].ParameterType, arguments [i]);
2244
void WriteCustomAttributeFixedArgument (TypeReference type, CustomAttributeArgument argument)
2247
WriteCustomAttributeFixedArrayArgument ((ArrayType) type, argument);
2251
WriteCustomAttributeElement (type, argument);
2254
void WriteCustomAttributeFixedArrayArgument (ArrayType type, CustomAttributeArgument argument)
2256
var values = argument.Value as CustomAttributeArgument [];
2258
if (values == null) {
2259
WriteUInt32 (0xffffffff);
2263
WriteInt32 (values.Length);
2265
if (values.Length == 0)
2268
var element_type = type.ElementType;
2270
for (int i = 0; i < values.Length; i++)
2271
WriteCustomAttributeElement (element_type, values [i]);
2274
void WriteCustomAttributeElement (TypeReference type, CustomAttributeArgument argument)
2277
WriteCustomAttributeFixedArrayArgument ((ArrayType) type, argument);
2281
if (type.etype == ElementType.Object) {
2282
WriteCustomAttributeFieldOrPropType (argument.Type);
2283
WriteCustomAttributeElement (argument.Type, argument);
2287
WriteCustomAttributeValue (type, argument.Value);
2290
void WriteCustomAttributeValue (TypeReference type, object value)
2292
var etype = type.etype;
2295
case ElementType.String:
2296
var @string = (string) value;
2297
if (@string == null)
2300
WriteUTF8String (@string);
2302
case ElementType.None:
2303
if (type.IsTypeOf ("System", "Type"))
2304
WriteTypeReference ((TypeReference) value);
2306
WriteCustomAttributeEnumValue (type, value);
2309
WritePrimitiveValue (value);
2314
void WritePrimitiveValue (object value)
2317
throw new ArgumentNullException ();
2319
switch (Type.GetTypeCode (value.GetType ())) {
2320
case TypeCode.Boolean:
2321
WriteByte ((byte) (((bool) value) ? 1 : 0));
2324
WriteByte ((byte) value);
2326
case TypeCode.SByte:
2327
WriteSByte ((sbyte) value);
2329
case TypeCode.Int16:
2330
WriteInt16 ((short) value);
2332
case TypeCode.UInt16:
2333
WriteUInt16 ((ushort) value);
2336
WriteInt16 ((short) (char) value);
2338
case TypeCode.Int32:
2339
WriteInt32 ((int) value);
2341
case TypeCode.UInt32:
2342
WriteUInt32 ((uint) value);
2344
case TypeCode.Single:
2345
WriteSingle ((float) value);
2347
case TypeCode.Int64:
2348
WriteInt64 ((long) value);
2350
case TypeCode.UInt64:
2351
WriteUInt64 ((ulong) value);
2353
case TypeCode.Double:
2354
WriteDouble ((double) value);
2357
throw new NotSupportedException (value.GetType ().FullName);
2361
void WriteCustomAttributeEnumValue (TypeReference enum_type, object value)
2363
var type = enum_type.CheckedResolve ();
2365
throw new ArgumentException ();
2367
WriteCustomAttributeValue (type.GetEnumUnderlyingType (), value);
2370
void WriteCustomAttributeFieldOrPropType (TypeReference type)
2373
var array = (ArrayType) type;
2374
WriteElementType (ElementType.SzArray);
2375
WriteCustomAttributeFieldOrPropType (array.ElementType);
2379
var etype = type.etype;
2382
case ElementType.Object:
2383
WriteElementType (ElementType.Boxed);
2385
case ElementType.None:
2386
if (type.IsTypeOf ("System", "Type"))
2387
WriteElementType (ElementType.Type);
2389
WriteElementType (ElementType.Enum);
2390
WriteTypeReference (type);
2394
WriteElementType (etype);
2399
public void WriteCustomAttributeNamedArguments (CustomAttribute attribute)
2401
var count = GetNamedArgumentCount (attribute);
2403
WriteUInt16 ((ushort) count);
2408
WriteICustomAttributeNamedArguments (attribute);
2411
static int GetNamedArgumentCount (ICustomAttribute attribute)
2415
if (attribute.HasFields)
2416
count += attribute.Fields.Count;
2418
if (attribute.HasProperties)
2419
count += attribute.Properties.Count;
2424
void WriteICustomAttributeNamedArguments (ICustomAttribute attribute)
2426
if (attribute.HasFields)
2427
WriteCustomAttributeNamedArguments (0x53, attribute.Fields);
2429
if (attribute.HasProperties)
2430
WriteCustomAttributeNamedArguments (0x54, attribute.Properties);
2433
void WriteCustomAttributeNamedArguments (byte kind, Collection<CustomAttributeNamedArgument> named_arguments)
2435
for (int i = 0; i < named_arguments.Count; i++)
2436
WriteCustomAttributeNamedArgument (kind, named_arguments [i]);
2439
void WriteCustomAttributeNamedArgument (byte kind, CustomAttributeNamedArgument named_argument)
2441
var argument = named_argument.Argument;
2444
WriteCustomAttributeFieldOrPropType (argument.Type);
2445
WriteUTF8String (named_argument.Name);
2446
WriteCustomAttributeFixedArgument (argument.Type, argument);
2449
public void WriteSecurityAttribute (SecurityAttribute attribute)
2451
WriteTypeReference (attribute.AttributeType);
2453
var count = GetNamedArgumentCount (attribute);
2456
WriteCompressedUInt32 (0); // length
2457
WriteCompressedUInt32 (0); // count
2461
var buffer = new SignatureWriter (metadata);
2462
buffer.WriteCompressedUInt32 ((uint) count);
2463
buffer.WriteICustomAttributeNamedArguments (attribute);
2465
WriteCompressedUInt32 ((uint) buffer.length);
2466
WriteBytes (buffer);
2469
void WriteTypeReference (TypeReference type)
2471
WriteUTF8String (TypeParser.ToParseable (type));
2474
public void WriteMarshalInfo (MarshalInfo marshal_info)
2476
WriteNativeType (marshal_info.native);
2478
switch (marshal_info.native) {
2479
case NativeType.Array: {
2480
var array = (ArrayMarshalInfo) marshal_info;
2481
if (array.element_type != NativeType.None)
2482
WriteNativeType (array.element_type);
2483
if (array.size_parameter_index > -1)
2484
WriteCompressedUInt32 ((uint) array.size_parameter_index);
2485
if (array.size > -1)
2486
WriteCompressedUInt32 ((uint) array.size);
2487
if (array.size_parameter_multiplier > -1)
2488
WriteCompressedUInt32 ((uint) array.size_parameter_multiplier);
2491
case NativeType.SafeArray: {
2492
var array = (SafeArrayMarshalInfo) marshal_info;
2493
if (array.element_type != VariantType.None)
2494
WriteVariantType (array.element_type);
2497
case NativeType.FixedArray: {
2498
var array = (FixedArrayMarshalInfo) marshal_info;
2499
if (array.size > -1)
2500
WriteCompressedUInt32 ((uint) array.size);
2501
if (array.element_type != NativeType.None)
2502
WriteNativeType (array.element_type);
2505
case NativeType.FixedSysString:
2506
var sys_string = (FixedSysStringMarshalInfo) marshal_info;
2507
if (sys_string.size > -1)
2508
WriteCompressedUInt32 ((uint) sys_string.size);
2510
case NativeType.CustomMarshaler:
2511
var marshaler = (CustomMarshalInfo) marshal_info;
2512
WriteUTF8String (marshaler.guid != Guid.Empty ? marshaler.guid.ToString () : string.Empty);
2513
WriteUTF8String (marshaler.unmanaged_type);
2514
WriteTypeReference (marshaler.managed_type);
2515
WriteUTF8String (marshaler.cookie);
2520
void WriteNativeType (NativeType native)
2522
WriteByte ((byte) native);
2525
void WriteVariantType (VariantType variant)
2527
WriteByte ((byte) variant);