/Mono.Cecil/AssemblyWriter.cs
http://github.com/jbevain/cecil · C# · 3334 lines · 2662 code · 659 blank · 13 comment · 387 complexity · c49fef0cb35b6db20b02f33df08c51b7 MD5 · raw file
Large files are truncated click here to view the full file
- //
- // Author:
- // Jb Evain (jbevain@gmail.com)
- //
- // Copyright (c) 2008 - 2015 Jb Evain
- // Copyright (c) 2008 - 2011 Novell, Inc.
- //
- // Licensed under the MIT/X11 license.
- //
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.IO.Compression;
- using System.Text;
- using System.Security.Cryptography;
- using Mono;
- using Mono.Collections.Generic;
- using Mono.Cecil.Cil;
- using Mono.Cecil.Metadata;
- using Mono.Cecil.PE;
- using RVA = System.UInt32;
- using RID = System.UInt32;
- using CodedRID = System.UInt32;
- using StringIndex = System.UInt32;
- using BlobIndex = System.UInt32;
- using GuidIndex = System.UInt32;
- namespace Mono.Cecil {
- using ModuleRow = Row<StringIndex, GuidIndex>;
- using TypeRefRow = Row<CodedRID, StringIndex, StringIndex>;
- using TypeDefRow = Row<TypeAttributes, StringIndex, StringIndex, CodedRID, RID, RID>;
- using FieldRow = Row<FieldAttributes, StringIndex, BlobIndex>;
- using MethodRow = Row<RVA, MethodImplAttributes, MethodAttributes, StringIndex, BlobIndex, RID>;
- using ParamRow = Row<ParameterAttributes, ushort, StringIndex>;
- using InterfaceImplRow = Row<uint, CodedRID>;
- using MemberRefRow = Row<CodedRID, StringIndex, BlobIndex>;
- using ConstantRow = Row<ElementType, CodedRID, BlobIndex>;
- using CustomAttributeRow = Row<CodedRID, CodedRID, BlobIndex>;
- using FieldMarshalRow = Row<CodedRID, BlobIndex>;
- using DeclSecurityRow = Row<SecurityAction, CodedRID, BlobIndex>;
- using ClassLayoutRow = Row<ushort, uint, RID>;
- using FieldLayoutRow = Row<uint, RID>;
- using EventMapRow = Row<RID, RID>;
- using EventRow = Row<EventAttributes, StringIndex, CodedRID>;
- using PropertyMapRow = Row<RID, RID>;
- using PropertyRow = Row<PropertyAttributes, StringIndex, BlobIndex>;
- using MethodSemanticsRow = Row<MethodSemanticsAttributes, RID, CodedRID>;
- using MethodImplRow = Row<RID, CodedRID, CodedRID>;
- using ImplMapRow = Row<PInvokeAttributes, CodedRID, StringIndex, RID>;
- using FieldRVARow = Row<RVA, RID>;
- using AssemblyRow = Row<AssemblyHashAlgorithm, ushort, ushort, ushort, ushort, AssemblyAttributes, uint, uint, uint>;
- using AssemblyRefRow = Row<ushort, ushort, ushort, ushort, AssemblyAttributes, uint, uint, uint, uint>;
- using FileRow = Row<FileAttributes, StringIndex, BlobIndex>;
- using ExportedTypeRow = Row<TypeAttributes, uint, StringIndex, StringIndex, CodedRID>;
- using ManifestResourceRow = Row<uint, ManifestResourceAttributes, StringIndex, CodedRID>;
- using NestedClassRow = Row<RID, RID>;
- using GenericParamRow = Row<ushort, GenericParameterAttributes, CodedRID, StringIndex>;
- using MethodSpecRow = Row<CodedRID, BlobIndex>;
- using GenericParamConstraintRow = Row<RID, CodedRID>;
- using DocumentRow = Row<BlobIndex, GuidIndex, BlobIndex, GuidIndex>;
- using MethodDebugInformationRow = Row<RID, BlobIndex>;
- using LocalScopeRow = Row<RID, RID, RID, RID, uint, uint>;
- using LocalVariableRow = Row<VariableAttributes, ushort, StringIndex>;
- using LocalConstantRow = Row<StringIndex, BlobIndex>;
- using ImportScopeRow = Row<RID, BlobIndex>;
- using StateMachineMethodRow = Row<RID, RID>;
- using CustomDebugInformationRow = Row<CodedRID, GuidIndex, BlobIndex>;
- static class ModuleWriter {
- public static void WriteModule (ModuleDefinition module, Disposable<Stream> stream, WriterParameters parameters)
- {
- using (stream)
- Write (module, stream, parameters);
- }
- static void Write (ModuleDefinition module, Disposable<Stream> stream, WriterParameters parameters)
- {
- if ((module.Attributes & ModuleAttributes.ILOnly) == 0)
- throw new NotSupportedException ("Writing mixed-mode assemblies is not supported");
- if (module.HasImage && module.ReadingMode == ReadingMode.Deferred) {
- var immediate_reader = new ImmediateModuleReader (module.Image);
- immediate_reader.ReadModule (module, resolve_attributes: false);
- immediate_reader.ReadSymbols (module);
- }
- module.MetadataSystem.Clear ();
- if (module.symbol_reader != null)
- module.symbol_reader.Dispose ();
- var name = module.assembly != null ? module.assembly.Name : null;
- var fq_name = stream.value.GetFileName ();
- var timestamp = parameters.Timestamp ?? module.timestamp;
- var symbol_writer_provider = parameters.SymbolWriterProvider;
- if (symbol_writer_provider == null && parameters.WriteSymbols)
- symbol_writer_provider = new DefaultSymbolWriterProvider ();
- if (parameters.HasStrongNameKey && name != null) {
- name.PublicKey = CryptoService.GetPublicKey (parameters);
- module.Attributes |= ModuleAttributes.StrongNameSigned;
- }
- if (parameters.DeterministicMvid)
- module.Mvid = Guid.Empty;
- var metadata = new MetadataBuilder (module, fq_name, timestamp, symbol_writer_provider);
- try {
- module.metadata_builder = metadata;
- using (var symbol_writer = GetSymbolWriter (module, fq_name, symbol_writer_provider, parameters)) {
- metadata.SetSymbolWriter (symbol_writer);
- BuildMetadata (module, metadata);
- if (parameters.DeterministicMvid)
- metadata.ComputeDeterministicMvid ();
- var writer = ImageWriter.CreateWriter (module, metadata, stream);
- stream.value.SetLength (0);
- writer.WriteImage ();
- if (parameters.HasStrongNameKey)
- CryptoService.StrongName (stream.value, writer, parameters);
- }
- } finally {
- module.metadata_builder = null;
- }
- }
- static void BuildMetadata (ModuleDefinition module, MetadataBuilder metadata)
- {
- if (!module.HasImage) {
- metadata.BuildMetadata ();
- return;
- }
- module.Read (metadata, (builder, _) => {
- builder.BuildMetadata ();
- return builder;
- });
- }
- static ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fq_name, ISymbolWriterProvider symbol_writer_provider, WriterParameters parameters)
- {
- if (symbol_writer_provider == null)
- return null;
- if (parameters.SymbolStream != null)
- return symbol_writer_provider.GetSymbolWriter (module, parameters.SymbolStream);
- return symbol_writer_provider.GetSymbolWriter (module, fq_name);
- }
- }
- abstract class MetadataTable {
- public abstract int Length { get; }
- public bool IsLarge {
- get { return Length > ushort.MaxValue; }
- }
- public abstract void Write (TableHeapBuffer buffer);
- public abstract void Sort ();
- }
- abstract class OneRowTable<TRow> : MetadataTable where TRow : struct {
- internal TRow row;
- public sealed override int Length {
- get { return 1; }
- }
- public sealed override void Sort ()
- {
- }
- }
- abstract class MetadataTable<TRow> : MetadataTable where TRow : struct {
- internal TRow [] rows = new TRow [2];
- internal int length;
- public sealed override int Length {
- get { return length; }
- }
- public int AddRow (TRow row)
- {
- if (rows.Length == length)
- Grow ();
- rows [length++] = row;
- return length;
- }
- void Grow ()
- {
- var rows = new TRow [this.rows.Length * 2];
- Array.Copy (this.rows, rows, this.rows.Length);
- this.rows = rows;
- }
- public override void Sort ()
- {
- }
- }
- abstract class SortedTable<TRow> : MetadataTable<TRow>, IComparer<TRow> where TRow : struct {
- public sealed override void Sort ()
- {
- MergeSort<TRow>.Sort (rows, 0, this.length, this);
- }
- protected static int Compare (uint x, uint y)
- {
- return x == y ? 0 : x > y ? 1 : -1;
- }
- public abstract int Compare (TRow x, TRow y);
- }
- sealed class ModuleTable : OneRowTable<ModuleRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- buffer.WriteUInt16 (0); // Generation
- buffer.WriteString (row.Col1); // Name
- buffer.WriteGuid (row.Col2); // Mvid
- buffer.WriteUInt16 (0); // EncId
- buffer.WriteUInt16 (0); // EncBaseId
- }
- }
- sealed class TypeRefTable : MetadataTable<TypeRefRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteCodedRID (
- rows [i].Col1, CodedIndex.ResolutionScope); // Scope
- buffer.WriteString (rows [i].Col2); // Name
- buffer.WriteString (rows [i].Col3); // Namespace
- }
- }
- }
- sealed class TypeDefTable : MetadataTable<TypeDefRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt32 ((uint) rows [i].Col1); // Attributes
- buffer.WriteString (rows [i].Col2); // Name
- buffer.WriteString (rows [i].Col3); // Namespace
- buffer.WriteCodedRID (
- rows [i].Col4, CodedIndex.TypeDefOrRef); // Extends
- buffer.WriteRID (rows [i].Col5, Table.Field); // FieldList
- buffer.WriteRID (rows [i].Col6, Table.Method); // MethodList
- }
- }
- }
- sealed class FieldTable : MetadataTable<FieldRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes
- buffer.WriteString (rows [i].Col2); // Name
- buffer.WriteBlob (rows [i].Col3); // Signature
- }
- }
- }
- sealed class MethodTable : MetadataTable<MethodRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt32 (rows [i].Col1); // RVA
- buffer.WriteUInt16 ((ushort) rows [i].Col2); // ImplFlags
- buffer.WriteUInt16 ((ushort) rows [i].Col3); // Flags
- buffer.WriteString (rows [i].Col4); // Name
- buffer.WriteBlob (rows [i].Col5); // Signature
- buffer.WriteRID (rows [i].Col6, Table.Param); // ParamList
- }
- }
- }
- sealed class ParamTable : MetadataTable<ParamRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes
- buffer.WriteUInt16 (rows [i].Col2); // Sequence
- buffer.WriteString (rows [i].Col3); // Name
- }
- }
- }
- sealed class InterfaceImplTable : MetadataTable<InterfaceImplRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class
- buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Interface
- }
- }
- /*public override int Compare (InterfaceImplRow x, InterfaceImplRow y)
- {
- return (int) (x.Col1 == y.Col1 ? y.Col2 - x.Col2 : x.Col1 - y.Col1);
- }*/
- }
- sealed class MemberRefTable : MetadataTable<MemberRefRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MemberRefParent);
- buffer.WriteString (rows [i].Col2);
- buffer.WriteBlob (rows [i].Col3);
- }
- }
- }
- sealed class ConstantTable : SortedTable<ConstantRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1);
- buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasConstant);
- buffer.WriteBlob (rows [i].Col3);
- }
- }
- public override int Compare (ConstantRow x, ConstantRow y)
- {
- return Compare (x.Col2, y.Col2);
- }
- }
- sealed class CustomAttributeTable : SortedTable<CustomAttributeRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasCustomAttribute); // Parent
- buffer.WriteCodedRID (rows [i].Col2, CodedIndex.CustomAttributeType); // Type
- buffer.WriteBlob (rows [i].Col3);
- }
- }
- public override int Compare (CustomAttributeRow x, CustomAttributeRow y)
- {
- return Compare (x.Col1, y.Col1);
- }
- }
- sealed class FieldMarshalTable : SortedTable<FieldMarshalRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasFieldMarshal);
- buffer.WriteBlob (rows [i].Col2);
- }
- }
- public override int Compare (FieldMarshalRow x, FieldMarshalRow y)
- {
- return Compare (x.Col1, y.Col1);
- }
- }
- sealed class DeclSecurityTable : SortedTable<DeclSecurityRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1);
- buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasDeclSecurity);
- buffer.WriteBlob (rows [i].Col3);
- }
- }
- public override int Compare (DeclSecurityRow x, DeclSecurityRow y)
- {
- return Compare (x.Col2, y.Col2);
- }
- }
- sealed class ClassLayoutTable : SortedTable<ClassLayoutRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 (rows [i].Col1); // PackingSize
- buffer.WriteUInt32 (rows [i].Col2); // ClassSize
- buffer.WriteRID (rows [i].Col3, Table.TypeDef); // Parent
- }
- }
- public override int Compare (ClassLayoutRow x, ClassLayoutRow y)
- {
- return Compare (x.Col3, y.Col3);
- }
- }
- sealed class FieldLayoutTable : SortedTable<FieldLayoutRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt32 (rows [i].Col1); // Offset
- buffer.WriteRID (rows [i].Col2, Table.Field); // Parent
- }
- }
- public override int Compare (FieldLayoutRow x, FieldLayoutRow y)
- {
- return Compare (x.Col2, y.Col2);
- }
- }
- sealed class StandAloneSigTable : MetadataTable<uint> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++)
- buffer.WriteBlob (rows [i]);
- }
- }
- sealed class EventMapTable : MetadataTable<EventMapRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent
- buffer.WriteRID (rows [i].Col2, Table.Event); // EventList
- }
- }
- }
- sealed class EventTable : MetadataTable<EventRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
- buffer.WriteString (rows [i].Col2); // Name
- buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeDefOrRef); // EventType
- }
- }
- }
- sealed class PropertyMapTable : MetadataTable<PropertyMapRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent
- buffer.WriteRID (rows [i].Col2, Table.Property); // PropertyList
- }
- }
- }
- sealed class PropertyTable : MetadataTable<PropertyRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
- buffer.WriteString (rows [i].Col2); // Name
- buffer.WriteBlob (rows [i].Col3); // Type
- }
- }
- }
- sealed class MethodSemanticsTable : SortedTable<MethodSemanticsRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
- buffer.WriteRID (rows [i].Col2, Table.Method); // Method
- buffer.WriteCodedRID (rows [i].Col3, CodedIndex.HasSemantics); // Association
- }
- }
- public override int Compare (MethodSemanticsRow x, MethodSemanticsRow y)
- {
- return Compare (x.Col3, y.Col3);
- }
- }
- sealed class MethodImplTable : MetadataTable<MethodImplRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class
- buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MethodDefOrRef); // MethodBody
- buffer.WriteCodedRID (rows [i].Col3, CodedIndex.MethodDefOrRef); // MethodDeclaration
- }
- }
- }
- sealed class ModuleRefTable : MetadataTable<uint> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++)
- buffer.WriteString (rows [i]); // Name
- }
- }
- sealed class TypeSpecTable : MetadataTable<uint> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++)
- buffer.WriteBlob (rows [i]); // Signature
- }
- }
- sealed class ImplMapTable : SortedTable<ImplMapRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
- buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MemberForwarded); // MemberForwarded
- buffer.WriteString (rows [i].Col3); // ImportName
- buffer.WriteRID (rows [i].Col4, Table.ModuleRef); // ImportScope
- }
- }
- public override int Compare (ImplMapRow x, ImplMapRow y)
- {
- return Compare (x.Col2, y.Col2);
- }
- }
- sealed class FieldRVATable : SortedTable<FieldRVARow> {
- internal int position;
- public override void Write (TableHeapBuffer buffer)
- {
- position = buffer.position;
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt32 (rows [i].Col1); // RVA
- buffer.WriteRID (rows [i].Col2, Table.Field); // Field
- }
- }
- public override int Compare (FieldRVARow x, FieldRVARow y)
- {
- return Compare (x.Col2, y.Col2);
- }
- }
- sealed class AssemblyTable : OneRowTable<AssemblyRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- buffer.WriteUInt32 ((uint) row.Col1); // AssemblyHashAlgorithm
- buffer.WriteUInt16 (row.Col2); // MajorVersion
- buffer.WriteUInt16 (row.Col3); // MinorVersion
- buffer.WriteUInt16 (row.Col4); // Build
- buffer.WriteUInt16 (row.Col5); // Revision
- buffer.WriteUInt32 ((uint) row.Col6); // Flags
- buffer.WriteBlob (row.Col7); // PublicKey
- buffer.WriteString (row.Col8); // Name
- buffer.WriteString (row.Col9); // Culture
- }
- }
- sealed class AssemblyRefTable : MetadataTable<AssemblyRefRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 (rows [i].Col1); // MajorVersion
- buffer.WriteUInt16 (rows [i].Col2); // MinorVersion
- buffer.WriteUInt16 (rows [i].Col3); // Build
- buffer.WriteUInt16 (rows [i].Col4); // Revision
- buffer.WriteUInt32 ((uint) rows [i].Col5); // Flags
- buffer.WriteBlob (rows [i].Col6); // PublicKeyOrToken
- buffer.WriteString (rows [i].Col7); // Name
- buffer.WriteString (rows [i].Col8); // Culture
- buffer.WriteBlob (rows [i].Col9); // Hash
- }
- }
- }
- sealed class FileTable : MetadataTable<FileRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt32 ((uint) rows [i].Col1);
- buffer.WriteString (rows [i].Col2);
- buffer.WriteBlob (rows [i].Col3);
- }
- }
- }
- sealed class ExportedTypeTable : MetadataTable<ExportedTypeRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt32 ((uint) rows [i].Col1);
- buffer.WriteUInt32 (rows [i].Col2);
- buffer.WriteString (rows [i].Col3);
- buffer.WriteString (rows [i].Col4);
- buffer.WriteCodedRID (rows [i].Col5, CodedIndex.Implementation);
- }
- }
- }
- sealed class ManifestResourceTable : MetadataTable<ManifestResourceRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt32 (rows [i].Col1);
- buffer.WriteUInt32 ((uint) rows [i].Col2);
- buffer.WriteString (rows [i].Col3);
- buffer.WriteCodedRID (rows [i].Col4, CodedIndex.Implementation);
- }
- }
- }
- sealed class NestedClassTable : SortedTable<NestedClassRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.TypeDef); // NestedClass
- buffer.WriteRID (rows [i].Col2, Table.TypeDef); // EnclosingClass
- }
- }
- public override int Compare (NestedClassRow x, NestedClassRow y)
- {
- return Compare (x.Col1, y.Col1);
- }
- }
- sealed class GenericParamTable : MetadataTable<GenericParamRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 (rows [i].Col1); // Number
- buffer.WriteUInt16 ((ushort) rows [i].Col2); // Flags
- buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeOrMethodDef); // Owner
- buffer.WriteString (rows [i].Col4); // Name
- }
- }
- }
- sealed class MethodSpecTable : MetadataTable<MethodSpecRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MethodDefOrRef); // Method
- buffer.WriteBlob (rows [i].Col2); // Instantiation
- }
- }
- }
- sealed class GenericParamConstraintTable : MetadataTable<GenericParamConstraintRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.GenericParam); // Owner
- buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Constraint
- }
- }
- }
- sealed class DocumentTable : MetadataTable<DocumentRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteBlob (rows [i].Col1); // Name
- buffer.WriteGuid (rows [i].Col2); // HashAlgorithm
- buffer.WriteBlob (rows [i].Col3); // Hash
- buffer.WriteGuid (rows [i].Col4); // Language
- }
- }
- }
- sealed class MethodDebugInformationTable : MetadataTable<MethodDebugInformationRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.Document); // Document
- buffer.WriteBlob (rows [i].Col2); // SequencePoints
- }
- }
- }
- sealed class LocalScopeTable : MetadataTable<LocalScopeRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.Method); // Method
- buffer.WriteRID (rows [i].Col2, Table.ImportScope); // ImportScope
- buffer.WriteRID (rows [i].Col3, Table.LocalVariable); // VariableList
- buffer.WriteRID (rows [i].Col4, Table.LocalConstant); // ConstantList
- buffer.WriteUInt32 (rows [i].Col5); // StartOffset
- buffer.WriteUInt32 (rows [i].Col6); // Length
- }
- }
- }
- sealed class LocalVariableTable : MetadataTable<LocalVariableRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes
- buffer.WriteUInt16 (rows [i].Col2); // Index
- buffer.WriteString (rows [i].Col3); // Name
- }
- }
- }
- sealed class LocalConstantTable : MetadataTable<LocalConstantRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteString (rows [i].Col1); // Name
- buffer.WriteBlob (rows [i].Col2); // Signature
- }
- }
- }
- sealed class ImportScopeTable : MetadataTable<ImportScopeRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.ImportScope); // Parent
- buffer.WriteBlob (rows [i].Col2); // Imports
- }
- }
- }
- sealed class StateMachineMethodTable : MetadataTable<StateMachineMethodRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteRID (rows [i].Col1, Table.Method); // MoveNextMethod
- buffer.WriteRID (rows [i].Col2, Table.Method); // KickoffMethod
- }
- }
- }
- sealed class CustomDebugInformationTable : SortedTable<CustomDebugInformationRow> {
- public override void Write (TableHeapBuffer buffer)
- {
- for (int i = 0; i < length; i++) {
- buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasCustomDebugInformation); // Parent
- buffer.WriteGuid (rows [i].Col2); // Kind
- buffer.WriteBlob (rows [i].Col3); // Value
- }
- }
- public override int Compare (CustomDebugInformationRow x, CustomDebugInformationRow y)
- {
- return Compare(x.Col1, y.Col1);
- }
- }
- sealed class MetadataBuilder {
- readonly internal ModuleDefinition module;
- readonly internal ISymbolWriterProvider symbol_writer_provider;
- internal ISymbolWriter symbol_writer;
- readonly internal TextMap text_map;
- readonly internal string fq_name;
- readonly internal uint timestamp;
- readonly Dictionary<TypeRefRow, MetadataToken> type_ref_map;
- readonly Dictionary<uint, MetadataToken> type_spec_map;
- readonly Dictionary<MemberRefRow, MetadataToken> member_ref_map;
- readonly Dictionary<MethodSpecRow, MetadataToken> method_spec_map;
- readonly Collection<GenericParameter> generic_parameters;
- readonly internal CodeWriter code;
- readonly internal DataBuffer data;
- readonly internal ResourceBuffer resources;
- readonly internal StringHeapBuffer string_heap;
- readonly internal GuidHeapBuffer guid_heap;
- readonly internal UserStringHeapBuffer user_string_heap;
- readonly internal BlobHeapBuffer blob_heap;
- readonly internal TableHeapBuffer table_heap;
- readonly internal PdbHeapBuffer pdb_heap;
- internal MetadataToken entry_point;
- internal RID type_rid = 1;
- internal RID field_rid = 1;
- internal RID method_rid = 1;
- internal RID param_rid = 1;
- internal RID property_rid = 1;
- internal RID event_rid = 1;
- internal RID local_variable_rid = 1;
- internal RID local_constant_rid = 1;
- readonly TypeRefTable type_ref_table;
- readonly TypeDefTable type_def_table;
- readonly FieldTable field_table;
- readonly MethodTable method_table;
- readonly ParamTable param_table;
- readonly InterfaceImplTable iface_impl_table;
- readonly MemberRefTable member_ref_table;
- readonly ConstantTable constant_table;
- readonly CustomAttributeTable custom_attribute_table;
- readonly DeclSecurityTable declsec_table;
- readonly StandAloneSigTable standalone_sig_table;
- readonly EventMapTable event_map_table;
- readonly EventTable event_table;
- readonly PropertyMapTable property_map_table;
- readonly PropertyTable property_table;
- readonly TypeSpecTable typespec_table;
- readonly MethodSpecTable method_spec_table;
- internal MetadataBuilder metadata_builder;
- readonly DocumentTable document_table;
- readonly MethodDebugInformationTable method_debug_information_table;
- readonly LocalScopeTable local_scope_table;
- readonly LocalVariableTable local_variable_table;
- readonly LocalConstantTable local_constant_table;
- readonly ImportScopeTable import_scope_table;
- readonly StateMachineMethodTable state_machine_method_table;
- readonly CustomDebugInformationTable custom_debug_information_table;
- readonly Dictionary<ImportScopeRow, MetadataToken> import_scope_map;
- readonly Dictionary<string, MetadataToken> document_map;
- public MetadataBuilder (ModuleDefinition module, string fq_name, uint timestamp, ISymbolWriterProvider symbol_writer_provider)
- {
- this.module = module;
- this.text_map = CreateTextMap ();
- this.fq_name = fq_name;
- this.timestamp = timestamp;
- this.symbol_writer_provider = symbol_writer_provider;
- this.code = new CodeWriter (this);
- this.data = new DataBuffer ();
- this.resources = new ResourceBuffer ();
- this.string_heap = new StringHeapBuffer ();
- this.guid_heap = new GuidHeapBuffer ();
- this.user_string_heap = new UserStringHeapBuffer ();
- this.blob_heap = new BlobHeapBuffer ();
- this.table_heap = new TableHeapBuffer (module, this);
- this.type_ref_table = GetTable<TypeRefTable> (Table.TypeRef);
- this.type_def_table = GetTable<TypeDefTable> (Table.TypeDef);
- this.field_table = GetTable<FieldTable> (Table.Field);
- this.method_table = GetTable<MethodTable> (Table.Method);
- this.param_table = GetTable<ParamTable> (Table.Param);
- this.iface_impl_table = GetTable<InterfaceImplTable> (Table.InterfaceImpl);
- this.member_ref_table = GetTable<MemberRefTable> (Table.MemberRef);
- this.constant_table = GetTable<ConstantTable> (Table.Constant);
- this.custom_attribute_table = GetTable<CustomAttributeTable> (Table.CustomAttribute);
- this.declsec_table = GetTable<DeclSecurityTable> (Table.DeclSecurity);
- this.standalone_sig_table = GetTable<StandAloneSigTable> (Table.StandAloneSig);
- this.event_map_table = GetTable<EventMapTable> (Table.EventMap);
- this.event_table = GetTable<EventTable> (Table.Event);
- this.property_map_table = GetTable<PropertyMapTable> (Table.PropertyMap);
- this.property_table = GetTable<PropertyTable> (Table.Property);
- this.typespec_table = GetTable<TypeSpecTable> (Table.TypeSpec);
- this.method_spec_table = GetTable<MethodSpecTable> (Table.MethodSpec);
- var row_equality_comparer = new RowEqualityComparer ();
- type_ref_map = new Dictionary<TypeRefRow, MetadataToken> (row_equality_comparer);
- type_spec_map = new Dictionary<uint, MetadataToken> ();
- member_ref_map = new Dictionary<MemberRefRow, MetadataToken> (row_equality_comparer);
- method_spec_map = new Dictionary<MethodSpecRow, MetadataToken> (row_equality_comparer);
- generic_parameters = new Collection<GenericParameter> ();
- this.document_table = GetTable<DocumentTable> (Table.Document);
- this.method_debug_information_table = GetTable<MethodDebugInformationTable> (Table.MethodDebugInformation);
- this.local_scope_table = GetTable<LocalScopeTable> (Table.LocalScope);
- this.local_variable_table = GetTable<LocalVariableTable> (Table.LocalVariable);
- this.local_constant_table = GetTable<LocalConstantTable> (Table.LocalConstant);
- this.import_scope_table = GetTable<ImportScopeTable> (Table.ImportScope);
- this.state_machine_method_table = GetTable<StateMachineMethodTable> (Table.StateMachineMethod);
- this.custom_debug_information_table = GetTable<CustomDebugInformationTable> (Table.CustomDebugInformation);
- this.document_map = new Dictionary<string, MetadataToken> (StringComparer.Ordinal);
- this.import_scope_map = new Dictionary<ImportScopeRow, MetadataToken> (row_equality_comparer);
- }
- public MetadataBuilder (ModuleDefinition module, PortablePdbWriterProvider writer_provider)
- {
- this.module = module;
- this.text_map = new TextMap ();
- this.symbol_writer_provider = writer_provider;
- this.string_heap = new StringHeapBuffer ();
- this.guid_heap = new GuidHeapBuffer ();
- this.user_string_heap = new UserStringHeapBuffer ();
- this.blob_heap = new BlobHeapBuffer ();
- this.table_heap = new TableHeapBuffer (module, this);
- this.pdb_heap = new PdbHeapBuffer();
- this.document_table = GetTable<DocumentTable> (Table.Document);
- this.method_debug_information_table = GetTable<MethodDebugInformationTable> (Table.MethodDebugInformation);
- this.local_scope_table = GetTable<LocalScopeTable> (Table.LocalScope);
- this.local_variable_table = GetTable<LocalVariableTable> (Table.LocalVariable);
- this.local_constant_table = GetTable<LocalConstantTable> (Table.LocalConstant);
- this.import_scope_table = GetTable<ImportScopeTable> (Table.ImportScope);
- this.state_machine_method_table = GetTable<StateMachineMethodTable> (Table.StateMachineMethod);
- this.custom_debug_information_table = GetTable<CustomDebugInformationTable> (Table.CustomDebugInformation);
- var row_equality_comparer = new RowEqualityComparer ();
- this.document_map = new Dictionary<string, MetadataToken> ();
- this.import_scope_map = new Dictionary<ImportScopeRow, MetadataToken> (row_equality_comparer);
- }
- public void SetSymbolWriter (ISymbolWriter writer)
- {
- symbol_writer = writer;
- if (symbol_writer == null && module.HasImage && module.Image.HasDebugTables ())
- symbol_writer = new PortablePdbWriter (this, module);
- }
- TextMap CreateTextMap ()
- {
- var map = new TextMap ();
- map.AddMap (TextSegment.ImportAddressTable, module.Architecture == TargetArchitecture.I386 ? 8 : 0);
- map.AddMap (TextSegment.CLIHeader, 0x48, 8);
- return map;
- }
- TTable GetTable<TTable> (Table table) where TTable : MetadataTable, new ()
- {
- return table_heap.GetTable<TTable> (table);
- }
- uint GetStringIndex (string @string)
- {
- if (string.IsNullOrEmpty (@string))
- return 0;
- return string_heap.GetStringIndex (@string);
- }
- uint GetGuidIndex (Guid guid)
- {
- return guid_heap.GetGuidIndex (guid);
- }
- uint GetBlobIndex (ByteBuffer blob)
- {
- if (blob.length == 0)
- return 0;
- return blob_heap.GetBlobIndex (blob);
- }
- uint GetBlobIndex (byte [] blob)
- {
- if (blob.IsNullOrEmpty ())
- return 0;
- return GetBlobIndex (new ByteBuffer (blob));
- }
- public void BuildMetadata ()
- {
- BuildModule ();
- table_heap.string_offsets = string_heap.WriteStrings ();
- table_heap.ComputeTableInformations ();
- table_heap.WriteTableHeap ();
- }
- void BuildModule ()
- {
- var table = GetTable<ModuleTable> (Table.Module);
- table.row.Col1 = GetStringIndex (module.Name);
- table.row.Col2 = GetGuidIndex (module.Mvid);
- var assembly = module.Assembly;
- if (assembly != null)
- BuildAssembly ();
- if (module.HasAssemblyReferences)
- AddAssemblyReferences ();
- if (module.HasModuleReferences)
- AddModuleReferences ();
- if (module.HasResources)
- AddResources ();
- if (module.HasExportedTypes)
- AddExportedTypes ();
- BuildTypes ();
- if (assembly != null) {
- if (assembly.HasCustomAttributes)
- AddCustomAttributes (assembly);
- if (assembly.HasSecurityDeclarations)
- AddSecurityDeclarations (assembly);
- }
- if (module.HasCustomAttributes)
- AddCustomAttributes (module);
- if (module.EntryPoint != null)
- entry_point = LookupToken (module.EntryPoint);
- }
- void BuildAssembly ()
- {
- var assembly = module.Assembly;
- var name = assembly.Name;
- var table = GetTable<AssemblyTable> (Table.Assembly);
- table.row = new AssemblyRow (
- name.HashAlgorithm,
- (ushort) name.Version.Major,
- (ushort) name.Version.Minor,
- (ushort) name.Version.Build,
- (ushort) name.Version.Revision,
- name.Attributes,
- GetBlobIndex (name.PublicKey),
- GetStringIndex (name.Name),
- GetStringIndex (name.Culture));
- if (assembly.Modules.Count > 1)
- BuildModules ();
- }
- void BuildModules ()
- {
- var modules = this.module.Assembly.Modules;
- var table = GetTable<FileTable> (Table.File);
- for (int i = 0; i < modules.Count; i++) {
- var module = modules [i];
- if (module.IsMain)
- continue;
- #if NET_CORE
- throw new NotSupportedException ();
- #else
- var parameters = new WriterParameters {
- SymbolWriterProvider = symbol_writer_provider,
- };
- var file_name = GetModuleFileName (module.Name);
- module.Write (file_name, parameters);
- var hash = CryptoService.ComputeHash (file_name);
- table.AddRow (new FileRow (
- FileAttributes.ContainsMetaData,
- GetStringIndex (module.Name),
- GetBlobIndex (hash)));
- #endif
- }
- }
- #if !NET_CORE
- string GetModuleFileName (string name)
- {
- if (string.IsNullOrEmpty (name))
- throw new NotSupportedException ();
- var path = Path.GetDirectoryName (fq_name);
- return Path.Combine (path, name);
- }
- #endif
- void AddAssemblyReferences ()
- {
- var references = module.AssemblyReferences;
- var table = GetTable<AssemblyRefTable> (Table.AssemblyRef);
- if (module.IsWindowsMetadata ())
- module.Projections.RemoveVirtualReferences (references);
- for (int i = 0; i < references.Count; i++) {
- var reference = references [i];
- var key_or_token = reference.PublicKey.IsNullOrEmpty ()
- ? reference.PublicKeyToken
- : reference.PublicKey;
- var version = reference.Version;
- var rid = table.AddRow (new AssemblyRefRow (
- (ushort) version.Major,
- (ushort) version.Minor,
- (ushort) version.Build,
- (ushort) version.Revision,
- reference.Attributes,
- GetBlobIndex (key_or_token),
- GetStringIndex (reference.Name),
- GetStringIndex (reference.Culture),
- GetBlobIndex (reference.Hash)));
- reference.token = new MetadataToken (TokenType.AssemblyRef, rid);
- }
- if (module.IsWindowsMetadata ())
- module.Projections.AddVirtualReferences (references);
- }
- void AddModuleReferences ()
- {
- var references = module.ModuleReferences;
- var table = GetTable<ModuleRefTable> (Table.ModuleRef);
- for (int i = 0; i < references.Count; i++) {
- var reference = references [i];
- reference.token = new MetadataToken (
- TokenType.ModuleRef,
- table.AddRow (GetStringIndex (reference.Name)));
- }
- }
- void AddResources ()
- {
- var resources = module.Resources;
- var table = GetTable<ManifestResourceTable> (Table.ManifestResource);
- for (int i = 0; i < resources.Count; i++) {
- var resource = resources [i];
- var row = new ManifestResourceRow (
- 0,
- resource.Attributes,
- GetStringIndex (resource.Name),
- 0);
- switch (resource.ResourceType) {
- case ResourceType.Embedded:
- row.Col1 = AddEmbeddedResource ((EmbeddedResource) resource);
- break;
- case ResourceType.Linked:
- row.Col4 = CodedIndex.Implementation.CompressMetadataToken (
- new MetadataToken (
- TokenType.File,
- AddLinkedResource ((LinkedResource) resource)));
- break;
- case ResourceType.AssemblyLinked:
- row.Col4 = CodedIndex.Implementation.CompressMetadataToken (
- ((AssemblyLinkedResource) resource).Assembly.MetadataToken);
- break;
- default:
- throw new NotSupportedException ();
- }
- table.AddRow (row);
- }
- }
- uint AddLinkedResource (LinkedResource resource)
- {
- var table = GetTable<FileTable> (Table.File);
- var hash = resource.Hash;
- if (hash.IsNullOrEmpty ())
- hash = CryptoService.ComputeHash (resource.File);
- return (uint) table.AddRow (new FileRow (
- FileAttributes.ContainsNoMetaData,
- GetStringIndex (resource.File),
- GetBlobIndex (hash)));
- }
- uint AddEmbeddedResource (EmbeddedResource resource)
- {
- return resources.AddResource (resource.GetResourceData ());
- }
- void AddExportedTypes ()
- {
- var exported_types = module.ExportedTypes;
- var table = GetTable<ExportedTypeTable> (Table.ExportedType);
- for (int i = 0; i < exported_types.Count; i++) {
- var exported_type = exported_types [i];
- var rid = table.AddRow (new ExportedTypeRow (
- exported_type.Attributes,
- (uint) exported_type.Identifier,
- GetStringIndex (exported_type.Name),
- GetStringIndex (exported_type.Namespace),
- MakeCodedRID (GetExportedTypeScope (exported_type), CodedIndex.Implementation)));
- exported_type.token = new MetadataToken (TokenType.ExportedType, rid);
- }
- }
- MetadataToken GetExportedTypeScope (ExportedType exported_type)
- {
- if (exported_type.DeclaringType != null)
- return exported_type.DeclaringType.MetadataToken;
- var scope = exported_type.Scope;
- switch (scope.MetadataToken.TokenType) {
- case TokenType.AssemblyRef:
- return scope.MetadataToken;
- case TokenType.ModuleRef:
- var file_table = GetTable<FileTable> (Table.File);
- for (int i = 0; i < file_table.length; i++)
- if (file_table.rows [i].Col2 == GetStringIndex (scope.Name))
- return new MetadataToken (TokenType.File, i + 1);
- break;
- }
- throw new NotSupportedException ();
- }
- void BuildTypes ()
- {
- if (!module.HasTypes)
- return;
- AttachTokens ();
- AddTypes ();
- AddGenericParameters ();
- }
- void AttachTokens ()
- {
- var types = module.Types;
- for (int i = 0; i < types.Count; i++)
- AttachTypeToken (types [i]);
- }
- void AttachTypeToken (TypeDefinition type)
- {
- type.token = new MetadataToken (TokenType.TypeDef, type_rid++);
- type.fields_range.Start = field_rid;
- type.methods_range.Start = method_rid;
- if (type.HasFields)
- AttachFieldsToken (type);
- if (type.HasMethods)
- AttachMethodsToken (type);
- if (type.HasNestedTypes)
- AttachNestedTypesToken (type);
- }
- void AttachNestedTypesToken (TypeDefinition type)
- {
- var nested_types = type.NestedTypes;
- for (int i = 0; i < nested_types.Count; i++)
- AttachTypeToken (nested_types [i]);
- }
- void AttachFieldsToken (TypeDefinition type)
- {
- var fields = type.Fields;
- type.fields_range.Length = (uint) fields.Count;
- for (int i = 0; i < fields.Count; i++)
- fields [i].token = new MetadataToken (TokenType.Field, field_rid++);
- }
- void AttachMethodsToken (TypeDefinition type)
- {
- var methods = type.Methods;
- type.methods_range.Length = (uint) methods.Count;
- for (int i = 0; i < methods.Count; i++)
- methods [i].token = new MetadataToken (TokenType.Method, method_rid++);
- }
- MetadataToken GetTypeToken (TypeReference type)
- {
- if (type == null)
- return MetadataToken.Zero;
- if (type.IsDefinition)
- return type.token;
- if (type.IsTypeSpecification ())
- return GetTypeSpecToken (type);
- return GetTypeRefToken (type);
- }
- MetadataToken GetTypeSpecToken (TypeReference type)
- {
- var row = GetBlobIndex (GetTypeSpecSignature (type));
- MetadataToken token;
- if (type_spec_map.TryGetValue (row, out token))
- return token;
- return AddTypeSpecification (type, row);
- }
- MetadataToken AddTypeSpecification (TypeReference type, uint row)
- {
- type.token = new MetadataToken (TokenType.TypeSpec, typespec_table.AddRow (row));
- var token = type.token;
- type_spec_map.Add (row, token);
- return token;
- }
- MetadataToken GetTypeRefToken (TypeReference type)
- {
- var projection = WindowsRuntimeProjections.RemoveProjection (type);
- var row = CreateTypeRefRow (type);
- MetadataToken token;
- if (!type_ref_map.TryGetValue (row, out token))
- token = AddTypeReference (type, row);
- WindowsRuntimeProjections.ApplyProjection (type, projection);
- return token;
- }
- TypeRefRow CreateTypeRefRow (TypeReference type)
- {
- var scope_token = GetScopeToken (type);
- return new TypeRefRow (
- MakeCodedRID (scope_token, CodedIndex.ResolutionScope),
- GetStringIndex (type.Name),
- GetStringIndex (type.Namespace));
- }
- MetadataToken GetScopeToken (TypeReference type)
- {
- if (type.IsNested)
- return GetTypeRefToken (type.DeclaringType);
- var scope = type.Scope;
- if (scope == null)
- return MetadataToken.Zero;
- return scope.MetadataToken;
- }
- static CodedRID MakeCodedRID (IMetadataTokenProvider provider, CodedIndex index)
- {
- return MakeCodedRID (provider.MetadataToken, index);
- }
- static CodedRID MakeCodedRID (MetadataToken token, CodedIndex index)
- {
- return index.CompressMetadataToken (token);
- }
- MetadataToken AddTypeReference (TypeReference type, TypeRefRow row)
- {
- type.token = new MetadataToken (TokenType.TypeRef, type_ref_table.AddRow (row));
- var token = type.token;
- type_ref_map.Add (row, token);
- return token;
- }
- void AddTypes ()
- {
- var types = module.Types;
- for (int i = 0; i < types.Count; i++)
- AddType (types [i]);
- }
- void AddType (TypeDefinition type)
- {
- var treatment = WindowsRuntimeProjections.RemoveProjection (type);
- type_def_table.AddRow (new TypeDefRow (
- type.Attributes,
- GetStringIndex (type.Name),
- GetStringIndex (type.Namespace),
- MakeCodedRID (GetTypeToken (type.BaseType), CodedIndex.TypeDefOrRef),
- type.fields_range.Start,
- type.methods_range.Start));
- if (type.HasGenericParameters)
- AddGenericParameters (type);
- if (type.HasInterfaces)
- AddInterfaces (type);
- AddLayoutInfo (type);
- if (type.HasFields)
- AddFields (type);
- if (type.HasMethods)
- AddMethods (type);
- if (type.HasProperties)
- AddProperties (type);
- if (type.HasEvents)
- AddEvents (type);
- if (type.HasCustomAttributes)
- AddCustomAttributes (type);
- if (type.HasSecurityDeclarations)
- AddSecurityDeclarations (type);
- if (type.HasNestedTypes)
- AddNestedTypes (type);
- WindowsRuntimeProjections.ApplyProjection (type, treatment);
- }
- void AddGenericParameters (IGenericParameterProvider owner)
- {
- var parameters = owner.GenericParameters;
- for (int i = 0; i < parameters.Count; i++)
- generic_parameters.Add (parameters [i]);
- }
- sealed class GenericParameterComparer : IComparer<GenericParameter> {
- public int Compare (GenericParameter a, GenericParameter b)
- {
- var a_owner = MakeCodedRID (a.Owner, CodedIndex.TypeOrMethodDef);
- var b_owner = MakeCodedRID (b.Owner, CodedIndex.TypeOrMethodDef);
- if (a_owner == b_owner) {
- var a_pos = a.Position;
- var b_pos = b.Position;
- return a_pos == b_pos ? 0 : a_pos > b_pos ? 1 : -1;
- }
- return a_owner > b_owner ? 1 : -1;
- }
- }
- void AddGenericParameters ()
- {
- var items = this.generic_parameters.items;
- var size = this.generic_parameters.size;
- Array.Sort (items, 0, size, new GenericParameterComparer ());
- var generic_param_table = GetTable<GenericParamTable> (Table.GenericParam);
- var generic_param_constraint_table = GetTable<GenericParamConstraintTable> (Table.GenericParamConstraint);
- for (int i = 0; i < size; i++) {
- var generic_parameter = items [i];
- var rid = generic_param_table.AddRow (new GenericParamRow (
- (ushort) generic_parameter.Position,
- generic_parameter.Attributes,
- MakeCodedRID (generic_parameter.Owner, CodedIndex.TypeOrMethodDef),
- GetStringIndex (generic_parameter.Name)));
- generic_parameter.token = new MetadataToken (TokenType.GenericParam, rid);
- if (generic_parameter.HasConstraints)
- AddConstraints (generic_parameter, generic_param_constraint_table);
- if (generic_parameter.HasCustomAttributes)
- AddCustomAttributes (generic_parameter);
- }
- }
- void AddConstraints (GenericParameter generic_parameter, GenericParamConstraintTable table)
- {
- var constraints = generic_parameter.Constraints;
- var gp_rid = generic_parameter.token.RID;
- for (int i = 0; i < constraints.Count; i++) {
- var constraint = constraints [i];
- var rid = table.AddRow (new GenericParamConstraintRow (
- gp_rid,
- MakeCodedRID (GetTypeToken (constraint.ConstraintType), CodedIndex.TypeDefOrRef)));
- constraint.token = new MetadataToken (TokenType.GenericParamConstraint, rid);
- if (constraint.HasCustomAttributes)
- AddCustomAttributes (constraint);
- }
- }
- void AddInterfaces (TypeDefinition type)
- {
- var interfaces = type.Interfaces;
- var type_rid = type.token.RID;
- for (int i = 0; i < interfaces.Count; i++) {
- var iface_impl = interfaces [i];
- var rid = iface_impl_table.AddRow (new InterfaceImplRow (
- type_rid,
- MakeCodedRID (GetTypeToken (iface_impl.InterfaceType), CodedIndex.TypeDefOrRef)));
- iface_impl.token = new MetadataToken (TokenType.InterfaceImpl, rid);
- if (iface_impl.HasCustomAttributes)
- AddCustomAttributes (iface_impl);
- }
- }
- void AddLayoutInfo (TypeDefinition type)
- {
- if (type.HasLayoutInfo) {
- var table = GetTable<ClassLayoutTable> (Table.ClassLayout);
- table.AddRow (new ClassLayoutRow (
- (ushort) type.PackingSize,
- (uint) type.ClassSize,
- type.token.RID));
- return;
- }
- if (type.IsValueType && HasNoInstanceField (type)) {
- var table = GetTable<ClassLayoutTable> (Table.ClassLayout);
- table.AddRow (new ClassLayoutRow (0, 1, type.token.RID));
- }
- }
- static bool HasNoInstanceField (TypeDefinition type)
- {
- if (!type.HasFields)
- return true;
- var fields = type.Fields;
- for (int i = 0; i < fields.Count; i++)
- if (!fields [i].IsStatic)
- return false;
- return true;
- }
- void AddNestedTypes (TypeDefinition type)
- {
- var nested_types = type.NestedTypes;
- var nested_table = GetTable<NestedClassTable> (Table.NestedClass);
- for (int i = 0; i < nested_types.Count; i++) {
- var nested = nested_types [i];
- AddType (nested);
- nested_table.AddRow (new NestedClassRow (nested.token.RID, type.token.RID));
- }
- }
- void AddFields (TypeDefinition type)
- {
- var fields = type.Fields;
- for (int i = 0; i < fields.Count; i++)
- AddField (fields [i]);
- }
- void AddField (FieldDefinition field)
- {
- var projection = WindowsRuntimeProjections.RemoveProjection (field);
- field_table.AddRow (new FieldRow (
- field.Attributes,
- GetStringIndex (field.Name),
- GetBlobIndex (GetFieldSignature (field))));
- if (!field.InitialValue.IsNullOrEmpty ())
- AddFieldRVA (field);
- if (field.HasLayoutInfo)
- AddFieldLayout (field);
- if (field.HasCustomAttributes)
- AddCustomAttributes (field);
- if (field.HasConstant)
- AddConstant (field, field.FieldType);
- if (field.HasMarshalInfo)
- AddMarshalInfo (field);
- WindowsRuntimeProjections.ApplyProjection (field, projection);
- }
- void AddFieldRVA (FieldDefinition field)
- {
- var table = GetTable<FieldRVATable> (Table.FieldRVA);
- table.AddRow (new FieldRVARow (
- data.AddData (field.InitialValue),
- field.token.RID));
- }
- void AddFieldLayout (FieldDefinition field)
- {
- var table = GetTable<FieldLayoutTable> (Table.FieldLayout);
- table.AddRow (new FieldLayoutRow ((uint) field.Offset, field.token.RID));
- }
- void AddMethods (TypeDefinition type)
- {
- var methods = type.Methods;
- for (int i = 0; i < methods.Count; i++)
- AddMethod (methods [i]);
- }
- void AddMethod (MethodDefinition method)
- {
- var projection = WindowsRuntimeProjections.RemoveProjection (method);
- method_table.AddRow (new MethodRow (
- method.HasBody ? code.WriteMethodBody (method) : 0,
- method.ImplAttributes,
- method.Attributes,
- GetStringIndex (method.Name),
- GetBlobIndex (GetMethodSignature (method)),
- param_rid));
- AddParameters (method);
- if (method.HasGenericParameters)
- AddGenericParameters (method);
- if (method.IsPInvokeImpl)
- AddPInvokeInfo (method);
- if (method.HasCustomAttributes)
- AddCustomAttributes (method);
- if (method.HasSecurityDeclarations)
- AddSecurityDeclarations (method);
- if (method.HasOverrides)
- AddOverrides (method);
- WindowsRuntimeProjections.ApplyProjection (method, projection);
- }
- void AddParameters (MethodDefinition method)
- {
- var return_parameter = method.MethodReturnType.parameter;
- if (return_parameter != null && RequiresParameterRow (return_parameter))
- AddParameter (0, return_parameter, param_table);
- if (!method.HasParameters)
- return;
- var parameters = method.Parameters;
- for (int i = 0; i < parameters.Count; i++) {
- var parameter = parameters [i];
- if (!RequiresParameterRow (parameter))
- continue;
- AddParameter ((ushort) (i + 1), parameter, param_table);
- }
- }
- v…