2 Copyright (C) 2009-2012 Jeroen Frijters
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
25 using System.Collections.Generic;
27 using IKVM.Reflection.Emit;
28 using IKVM.Reflection.Writer;
29 using IKVM.Reflection.Reader;
31 namespace IKVM.Reflection.Metadata
33 internal abstract class Table
39 get { return RowCount > 65535; }
42 internal abstract int RowCount { get; set; }
44 internal abstract void Write(MetadataWriter mw);
45 internal abstract void Read(MetadataReader mr);
47 internal int GetLength(MetadataWriter md)
49 return RowCount * GetRowSize(new RowSizeCalc(md));
52 protected abstract int GetRowSize(RowSizeCalc rsc);
54 protected sealed class RowSizeCalc
56 private readonly MetadataWriter mw;
59 internal RowSizeCalc(MetadataWriter mw)
64 internal RowSizeCalc AddFixed(int size)
70 internal RowSizeCalc WriteStringIndex()
83 internal RowSizeCalc WriteGuidIndex()
96 internal RowSizeCalc WriteBlobIndex()
109 internal RowSizeCalc WriteTypeDefOrRef()
111 if (mw.bigTypeDefOrRef)
122 internal RowSizeCalc WriteField()
135 internal RowSizeCalc WriteMethodDef()
148 internal RowSizeCalc WriteParam()
161 internal RowSizeCalc WriteResolutionScope()
163 if (mw.bigResolutionScope)
174 internal RowSizeCalc WriteMemberRefParent()
176 if (mw.bigMemberRefParent)
187 internal RowSizeCalc WriteHasCustomAttribute()
189 if (mw.bigHasCustomAttribute)
200 internal RowSizeCalc WriteCustomAttributeType()
202 if (mw.bigCustomAttributeType)
213 internal RowSizeCalc WriteHasConstant()
215 if (mw.bigHasConstant)
226 internal RowSizeCalc WriteTypeDef()
239 internal RowSizeCalc WriteMethodDefOrRef()
241 if (mw.bigMethodDefOrRef)
252 internal RowSizeCalc WriteEvent()
265 internal RowSizeCalc WriteProperty()
278 internal RowSizeCalc WriteHasSemantics()
280 if (mw.bigHasSemantics)
291 internal RowSizeCalc WriteImplementation()
293 if (mw.bigImplementation)
304 internal RowSizeCalc WriteTypeOrMethodDef()
306 if (mw.bigTypeOrMethodDef)
317 internal RowSizeCalc WriteGenericParam()
319 if (mw.bigGenericParam)
330 internal RowSizeCalc WriteHasDeclSecurity()
332 if (mw.bigHasDeclSecurity)
343 internal RowSizeCalc WriteMemberForwarded()
345 if (mw.bigMemberForwarded)
356 internal RowSizeCalc WriteModuleRef()
369 internal RowSizeCalc WriteHasFieldMarshal()
371 if (mw.bigHasFieldMarshal)
389 abstract class Table<T> : Table
391 internal T[] records = new T[1];
392 protected int rowCount;
394 internal sealed override int RowCount
396 get { return rowCount; }
397 set { rowCount = value; records = new T[value]; }
400 protected override int GetRowSize(RowSizeCalc rsc)
402 throw new InvalidOperationException();
405 internal int AddRecord(T newRecord)
407 if (rowCount == records.Length)
409 T[] newarr = new T[records.Length * 2];
410 Array.Copy(records, newarr, records.Length);
413 records[rowCount++] = newRecord;
417 internal int AddVirtualRecord()
422 internal override void Write(MetadataWriter mw)
424 throw new InvalidOperationException();
428 abstract class SortedTable<T> : Table<T>, IComparer<int>
429 where T : SortedTable<T>.ISortKey
431 internal interface ISortKey
436 internal struct Enumerable
438 private readonly SortedTable<T> table;
439 private readonly int token;
441 internal Enumerable(SortedTable<T> table, int token)
447 public Enumerator GetEnumerator()
449 T[] records = table.records;
452 return new Enumerator(records, table.RowCount - 1, -1, token);
454 int index = BinarySearch(records, table.RowCount, token & 0xFFFFFF);
457 return new Enumerator(null, 0, 1, -1);
460 while (start > 0 && (records[start - 1].Key & 0xFFFFFF) == (token & 0xFFFFFF))
465 int max = table.RowCount - 1;
466 while (end < max && (records[end + 1].Key & 0xFFFFFF) == (token & 0xFFFFFF))
470 return new Enumerator(records, end, start - 1, token);
473 private static int BinarySearch(T[] records, int length, int maskedToken)
476 int max = length - 1;
479 int mid = min + ((max - min) / 2);
480 int maskedValue = records[mid].Key & 0xFFFFFF;
481 if (maskedToken == maskedValue)
485 else if (maskedToken < maskedValue)
498 internal struct Enumerator
500 private readonly T[] records;
501 private readonly int token;
502 private readonly int max;
505 internal Enumerator(T[] records, int max, int index, int token)
507 this.records = records;
515 get { return index; }
518 public bool MoveNext()
523 if (records[index].Key == token)
532 internal Enumerable Filter(int token)
534 return new Enumerable(this, token);
537 protected void Sort()
539 int[] map = new int[rowCount];
540 for (int i = 0; i < map.Length; i++)
544 Array.Sort(map, this);
545 T[] newRecords = new T[rowCount];
546 for (int i = 0; i < map.Length; i++)
548 newRecords[i] = records[map[i]];
550 records = newRecords;
553 int IComparer<int>.Compare(int x, int y)
555 int rc = records[x].Key.CompareTo(records[y].Key);
556 return rc == 0 ? x.CompareTo(y) : rc;
560 sealed class ModuleTable : Table<ModuleTable.Record>
562 internal const int Index = 0x00;
564 internal struct Record
566 internal short Generation;
567 internal int Name; // -> StringHeap
568 internal int Mvid; // -> GuidHeap
569 internal int EncId; // -> GuidHeap
570 internal int EncBaseId; // -> GuidHeap
573 internal override void Read(MetadataReader mr)
575 for (int i = 0; i < records.Length; i++)
577 records[i].Generation = mr.ReadInt16();
578 records[i].Name = mr.ReadStringIndex();
579 records[i].Mvid = mr.ReadGuidIndex();
580 records[i].EncId = mr.ReadGuidIndex();
581 records[i].EncBaseId = mr.ReadGuidIndex();
585 internal override void Write(MetadataWriter mw)
587 for (int i = 0; i < rowCount; i++)
589 mw.Write(records[i].Generation);
590 mw.WriteStringIndex(records[i].Name);
591 mw.WriteGuidIndex(records[i].Mvid);
592 mw.WriteGuidIndex(records[i].EncId);
593 mw.WriteGuidIndex(records[i].EncBaseId);
597 protected override int GetRowSize(RowSizeCalc rsc)
608 internal void Add(short generation, int name, int mvid, int encid, int encbaseid)
610 Record record = new Record();
611 record.Generation = generation;
614 record.EncId = encid;
615 record.EncBaseId = encbaseid;
620 sealed class TypeRefTable : Table<TypeRefTable.Record>
622 internal const int Index = 0x01;
624 internal struct Record
626 internal int ResolutionScope;
627 internal int TypeName;
628 internal int TypeNameSpace;
631 internal override void Read(MetadataReader mr)
633 for (int i = 0; i < records.Length; i++)
635 records[i].ResolutionScope = mr.ReadResolutionScope();
636 records[i].TypeName = mr.ReadStringIndex();
637 records[i].TypeNameSpace = mr.ReadStringIndex();
641 internal override void Write(MetadataWriter mw)
643 for (int i = 0; i < rowCount; i++)
645 mw.WriteResolutionScope(records[i].ResolutionScope);
646 mw.WriteStringIndex(records[i].TypeName);
647 mw.WriteStringIndex(records[i].TypeNameSpace);
651 protected override int GetRowSize(RowSizeCalc rsc)
654 .WriteResolutionScope()
660 internal void Fixup(ModuleBuilder moduleBuilder)
662 for (int i = 0; i < rowCount; i++)
664 moduleBuilder.FixupPseudoToken(ref records[i].ResolutionScope);
669 sealed class TypeDefTable : Table<TypeDefTable.Record>
671 internal const int Index = 0x02;
673 internal struct Record
676 internal int TypeName;
677 internal int TypeNamespace;
678 internal int Extends;
679 internal int FieldList;
680 internal int MethodList;
683 internal override void Read(MetadataReader mr)
685 for (int i = 0; i < records.Length; i++)
687 records[i].Flags = mr.ReadInt32();
688 records[i].TypeName = mr.ReadStringIndex();
689 records[i].TypeNamespace = mr.ReadStringIndex();
690 records[i].Extends = mr.ReadTypeDefOrRef();
691 records[i].FieldList = mr.ReadField();
692 records[i].MethodList = mr.ReadMethodDef();
696 internal override void Write(MetadataWriter mw)
698 mw.ModuleBuilder.WriteTypeDefTable(mw);
701 internal int AllocToken()
703 return 0x02000000 + AddVirtualRecord();
706 protected override int GetRowSize(RowSizeCalc rsc)
719 sealed class FieldPtrTable : Table<int>
721 internal const int Index = 0x03;
723 internal override void Read(MetadataReader mr)
725 for (int i = 0; i < records.Length; i++)
727 records[i] = mr.ReadField();
732 sealed class FieldTable : Table<FieldTable.Record>
734 internal const int Index = 0x04;
736 internal struct Record
738 internal short Flags;
740 internal int Signature;
743 internal override void Read(MetadataReader mr)
745 for (int i = 0; i < records.Length; i++)
747 records[i].Flags = mr.ReadInt16();
748 records[i].Name = mr.ReadStringIndex();
749 records[i].Signature = mr.ReadBlobIndex();
753 internal override void Write(MetadataWriter mw)
755 mw.ModuleBuilder.WriteFieldTable(mw);
758 protected override int GetRowSize(RowSizeCalc rsc)
768 sealed class MethodPtrTable : Table<int>
770 internal const int Index = 0x05;
772 internal override void Read(MetadataReader mr)
774 for (int i = 0; i < records.Length; i++)
776 records[i] = mr.ReadMethodDef();
781 sealed class MethodDefTable : Table<MethodDefTable.Record>
783 internal const int Index = 0x06;
786 internal struct Record
789 internal short ImplFlags;
790 internal short Flags;
792 internal int Signature;
793 internal int ParamList;
796 internal override void Read(MetadataReader mr)
798 for (int i = 0; i < records.Length; i++)
800 records[i].RVA = mr.ReadInt32();
801 records[i].ImplFlags = mr.ReadInt16();
802 records[i].Flags = mr.ReadInt16();
803 records[i].Name = mr.ReadStringIndex();
804 records[i].Signature = mr.ReadBlobIndex();
805 records[i].ParamList = mr.ReadParam();
809 internal override void Write(MetadataWriter mw)
811 mw.ModuleBuilder.WriteMethodDefTable(baseRVA, mw);
814 protected override int GetRowSize(RowSizeCalc rsc)
824 internal void Fixup(TextSection code)
826 baseRVA = (int)code.MethodBodiesRVA;
830 sealed class ParamPtrTable : Table<int>
832 internal const int Index = 0x07;
834 internal override void Read(MetadataReader mr)
836 for (int i = 0; i < records.Length; i++)
838 records[i] = mr.ReadParam();
843 sealed class ParamTable : Table<ParamTable.Record>
845 internal const int Index = 0x08;
847 internal struct Record
849 internal short Flags;
850 internal short Sequence;
854 internal override void Read(MetadataReader mr)
856 for (int i = 0; i < records.Length; i++)
858 records[i].Flags = mr.ReadInt16();
859 records[i].Sequence = mr.ReadInt16();
860 records[i].Name = mr.ReadStringIndex();
864 internal override void Write(MetadataWriter mw)
866 mw.ModuleBuilder.WriteParamTable(mw);
869 protected override int GetRowSize(RowSizeCalc rsc)
878 sealed class InterfaceImplTable : SortedTable<InterfaceImplTable.Record>
880 internal const int Index = 0x09;
882 internal struct Record : ISortKey
885 internal int Interface;
889 get { return Class; }
893 internal override void Read(MetadataReader mr)
895 for (int i = 0; i < records.Length; i++)
897 records[i].Class = mr.ReadTypeDef();
898 records[i].Interface = mr.ReadTypeDefOrRef();
902 internal override void Write(MetadataWriter mw)
904 for (int i = 0; i < rowCount; i++)
906 mw.WriteTypeDef(records[i].Class);
907 mw.WriteEncodedTypeDefOrRef(records[i].Interface);
911 protected override int GetRowSize(RowSizeCalc rsc)
919 internal void Fixup()
921 for (int i = 0; i < rowCount; i++)
923 int token = records[i].Interface;
928 case TypeDefTable.Index:
929 token = (token & 0xFFFFFF) << 2 | 0;
931 case TypeRefTable.Index:
932 token = (token & 0xFFFFFF) << 2 | 1;
934 case TypeSpecTable.Index:
935 token = (token & 0xFFFFFF) << 2 | 2;
938 throw new InvalidOperationException();
940 records[i].Interface = token;
942 // LAMESPEC the CLI spec says that InterfaceImpl should be sorted by { Class, Interface },
943 // but it appears to only be necessary to sort by Class (and csc emits InterfaceImpl records in
944 // source file order, so to be able to support round tripping, we need to retain ordering as well).
949 sealed class MemberRefTable : Table<MemberRefTable.Record>
951 internal const int Index = 0x0A;
953 internal struct Record
957 internal int Signature;
960 internal override void Read(MetadataReader mr)
962 for (int i = 0; i < records.Length; i++)
964 records[i].Class = mr.ReadMemberRefParent();
965 records[i].Name = mr.ReadStringIndex();
966 records[i].Signature = mr.ReadBlobIndex();
970 internal override void Write(MetadataWriter mw)
972 for (int i = 0; i < rowCount; i++)
974 mw.WriteMemberRefParent(records[i].Class);
975 mw.WriteStringIndex(records[i].Name);
976 mw.WriteBlobIndex(records[i].Signature);
980 protected override int GetRowSize(RowSizeCalc rsc)
983 .WriteMemberRefParent()
989 internal int FindOrAddRecord(Record record)
991 for (int i = 0; i < rowCount; i++)
993 if (records[i].Class == record.Class
994 && records[i].Name == record.Name
995 && records[i].Signature == record.Signature)
1000 return AddRecord(record);
1003 internal void Fixup(ModuleBuilder moduleBuilder)
1005 for (int i = 0; i < rowCount; i++)
1007 moduleBuilder.FixupPseudoToken(ref records[i].Class);
1012 sealed class ConstantTable : SortedTable<ConstantTable.Record>
1014 internal const int Index = 0x0B;
1016 internal struct Record : ISortKey
1018 internal short Type;
1019 internal int Parent;
1024 get { return Parent; }
1028 internal override void Read(MetadataReader mr)
1030 for (int i = 0; i < records.Length; i++)
1032 records[i].Type = mr.ReadInt16();
1033 records[i].Parent = mr.ReadHasConstant();
1034 records[i].Value = mr.ReadBlobIndex();
1038 internal override void Write(MetadataWriter mw)
1040 for (int i = 0; i < rowCount; i++)
1042 mw.Write(records[i].Type);
1043 mw.WriteHasConstant(records[i].Parent);
1044 mw.WriteBlobIndex(records[i].Value);
1048 protected override int GetRowSize(RowSizeCalc rsc)
1057 internal void Fixup(ModuleBuilder moduleBuilder)
1059 for (int i = 0; i < rowCount; i++)
1061 int token = records[i].Parent;
1062 moduleBuilder.FixupPseudoToken(ref token);
1063 // do the HasConstant encoding, so that we can sort the table
1064 switch (token >> 24)
1066 case FieldTable.Index:
1067 records[i].Parent = (token & 0xFFFFFF) << 2 | 0;
1069 case ParamTable.Index:
1070 records[i].Parent = (token & 0xFFFFFF) << 2 | 1;
1072 case PropertyTable.Index:
1073 records[i].Parent = (token & 0xFFFFFF) << 2 | 2;
1076 throw new InvalidOperationException();
1082 internal object GetRawConstantValue(Module module, int parent)
1084 foreach (int i in Filter(parent))
1086 ByteReader br = module.GetBlob(module.Constant.records[i].Value);
1087 switch (module.Constant.records[i].Type)
1089 // see ModuleBuilder.AddConstant for the encodings
1090 case Signature.ELEMENT_TYPE_BOOLEAN:
1091 return br.ReadByte() != 0;
1092 case Signature.ELEMENT_TYPE_I1:
1093 return br.ReadSByte();
1094 case Signature.ELEMENT_TYPE_I2:
1095 return br.ReadInt16();
1096 case Signature.ELEMENT_TYPE_I4:
1097 return br.ReadInt32();
1098 case Signature.ELEMENT_TYPE_I8:
1099 return br.ReadInt64();
1100 case Signature.ELEMENT_TYPE_U1:
1101 return br.ReadByte();
1102 case Signature.ELEMENT_TYPE_U2:
1103 return br.ReadUInt16();
1104 case Signature.ELEMENT_TYPE_U4:
1105 return br.ReadUInt32();
1106 case Signature.ELEMENT_TYPE_U8:
1107 return br.ReadUInt64();
1108 case Signature.ELEMENT_TYPE_R4:
1109 return br.ReadSingle();
1110 case Signature.ELEMENT_TYPE_R8:
1111 return br.ReadDouble();
1112 case Signature.ELEMENT_TYPE_CHAR:
1113 return br.ReadChar();
1114 case Signature.ELEMENT_TYPE_STRING:
1116 char[] chars = new char[br.Length / 2];
1117 for (int j = 0; j < chars.Length; j++)
1119 chars[j] = br.ReadChar();
1121 return new String(chars);
1123 case Signature.ELEMENT_TYPE_CLASS:
1124 if (br.ReadInt32() != 0)
1126 throw new BadImageFormatException();
1130 throw new BadImageFormatException();
1133 throw new InvalidOperationException();
1137 sealed class CustomAttributeTable : SortedTable<CustomAttributeTable.Record>
1139 internal const int Index = 0x0C;
1141 internal struct Record : ISortKey
1143 internal int Parent;
1149 get { return Parent; }
1153 internal override void Read(MetadataReader mr)
1155 for (int i = 0; i < records.Length; i++)
1157 records[i].Parent = mr.ReadHasCustomAttribute();
1158 records[i].Type = mr.ReadCustomAttributeType();
1159 records[i].Value = mr.ReadBlobIndex();
1163 internal override void Write(MetadataWriter mw)
1165 for (int i = 0; i < rowCount; i++)
1167 mw.WriteHasCustomAttribute(records[i].Parent);
1168 mw.WriteCustomAttributeType(records[i].Type);
1169 mw.WriteBlobIndex(records[i].Value);
1173 protected override int GetRowSize(RowSizeCalc rsc)
1176 .WriteHasCustomAttribute()
1177 .WriteCustomAttributeType()
1182 internal void Fixup(ModuleBuilder moduleBuilder)
1184 int[] genericParamFixup = moduleBuilder.GenericParam.GetIndexFixup();
1185 for (int i = 0; i < rowCount; i++)
1187 moduleBuilder.FixupPseudoToken(ref records[i].Type);
1188 int token = records[i].Parent;
1189 moduleBuilder.FixupPseudoToken(ref token);
1190 // do the HasCustomAttribute encoding, so that we can sort the table
1191 switch (token >> 24)
1193 case MethodDefTable.Index:
1194 records[i].Parent = (token & 0xFFFFFF) << 5 | 0;
1196 case FieldTable.Index:
1197 records[i].Parent = (token & 0xFFFFFF) << 5 | 1;
1199 case TypeRefTable.Index:
1200 records[i].Parent = (token & 0xFFFFFF) << 5 | 2;
1202 case TypeDefTable.Index:
1203 records[i].Parent = (token & 0xFFFFFF) << 5 | 3;
1205 case ParamTable.Index:
1206 records[i].Parent = (token & 0xFFFFFF) << 5 | 4;
1208 case InterfaceImplTable.Index:
1209 records[i].Parent = (token & 0xFFFFFF) << 5 | 5;
1211 case MemberRefTable.Index:
1212 records[i].Parent = (token & 0xFFFFFF) << 5 | 6;
1214 case ModuleTable.Index:
1215 records[i].Parent = (token & 0xFFFFFF) << 5 | 7;
1217 // Permission (8) table doesn't exist in the spec
1218 case PropertyTable.Index:
1219 records[i].Parent = (token & 0xFFFFFF) << 5 | 9;
1221 case EventTable.Index:
1222 records[i].Parent = (token & 0xFFFFFF) << 5 | 10;
1224 case StandAloneSigTable.Index:
1225 records[i].Parent = (token & 0xFFFFFF) << 5 | 11;
1227 case ModuleRefTable.Index:
1228 records[i].Parent = (token & 0xFFFFFF) << 5 | 12;
1230 case TypeSpecTable.Index:
1231 records[i].Parent = (token & 0xFFFFFF) << 5 | 13;
1233 case AssemblyTable.Index:
1234 records[i].Parent = (token & 0xFFFFFF) << 5 | 14;
1236 case AssemblyRefTable.Index:
1237 records[i].Parent = (token & 0xFFFFFF) << 5 | 15;
1239 case FileTable.Index:
1240 records[i].Parent = (token & 0xFFFFFF) << 5 | 16;
1242 case ExportedTypeTable.Index:
1243 records[i].Parent = (token & 0xFFFFFF) << 5 | 17;
1245 case ManifestResourceTable.Index:
1246 records[i].Parent = (token & 0xFFFFFF) << 5 | 18;
1248 case GenericParamTable.Index:
1249 records[i].Parent = (genericParamFixup[(token & 0xFFFFFF) - 1] + 1) << 5 | 19;
1252 throw new InvalidOperationException();
1259 sealed class FieldMarshalTable : SortedTable<FieldMarshalTable.Record>
1261 internal const int Index = 0x0D;
1263 internal struct Record : ISortKey
1265 internal int Parent;
1266 internal int NativeType;
1270 get { return Parent; }
1274 internal override void Read(MetadataReader mr)
1276 for (int i = 0; i < records.Length; i++)
1278 records[i].Parent = mr.ReadHasFieldMarshal();
1279 records[i].NativeType = mr.ReadBlobIndex();
1283 internal override void Write(MetadataWriter mw)
1285 for (int i = 0; i < rowCount; i++)
1287 mw.WriteHasFieldMarshal(records[i].Parent);
1288 mw.WriteBlobIndex(records[i].NativeType);
1292 protected override int GetRowSize(RowSizeCalc rsc)
1295 .WriteHasFieldMarshal()
1300 internal void Fixup(ModuleBuilder moduleBuilder)
1302 for (int i = 0; i < rowCount; i++)
1304 int token = moduleBuilder.ResolvePseudoToken(records[i].Parent);
1305 // do the HasFieldMarshal encoding, so that we can sort the table
1306 switch (token >> 24)
1308 case FieldTable.Index:
1309 records[i].Parent = (token & 0xFFFFFF) << 1 | 0;
1311 case ParamTable.Index:
1312 records[i].Parent = (token & 0xFFFFFF) << 1 | 1;
1315 throw new InvalidOperationException();
1322 sealed class DeclSecurityTable : SortedTable<DeclSecurityTable.Record>
1324 internal const int Index = 0x0E;
1326 internal struct Record : ISortKey
1328 internal short Action;
1329 internal int Parent;
1330 internal int PermissionSet;
1334 get { return Parent; }
1338 internal override void Read(MetadataReader mr)
1340 for (int i = 0; i < records.Length; i++)
1342 records[i].Action = mr.ReadInt16();
1343 records[i].Parent = mr.ReadHasDeclSecurity();
1344 records[i].PermissionSet = mr.ReadBlobIndex();
1348 internal override void Write(MetadataWriter mw)
1350 for (int i = 0; i < rowCount; i++)
1352 mw.Write(records[i].Action);
1353 mw.WriteHasDeclSecurity(records[i].Parent);
1354 mw.WriteBlobIndex(records[i].PermissionSet);
1358 protected override int GetRowSize(RowSizeCalc rsc)
1362 .WriteHasDeclSecurity()
1367 internal void Fixup(ModuleBuilder moduleBuilder)
1369 for (int i = 0; i < rowCount; i++)
1371 int token = records[i].Parent;
1372 moduleBuilder.FixupPseudoToken(ref token);
1373 // do the HasDeclSecurity encoding, so that we can sort the table
1374 switch (token >> 24)
1376 case TypeDefTable.Index:
1377 token = (token & 0xFFFFFF) << 2 | 0;
1379 case MethodDefTable.Index:
1380 token = (token & 0xFFFFFF) << 2 | 1;
1382 case AssemblyTable.Index:
1383 token = (token & 0xFFFFFF) << 2 | 2;
1386 throw new InvalidOperationException();
1388 records[i].Parent = token;
1394 sealed class ClassLayoutTable : SortedTable<ClassLayoutTable.Record>
1396 internal const int Index = 0x0f;
1398 internal struct Record : ISortKey
1400 internal short PackingSize;
1401 internal int ClassSize;
1402 internal int Parent;
1406 get { return Parent; }
1410 internal override void Read(MetadataReader mr)
1412 for (int i = 0; i < records.Length; i++)
1414 records[i].PackingSize = mr.ReadInt16();
1415 records[i].ClassSize = mr.ReadInt32();
1416 records[i].Parent = mr.ReadTypeDef();
1420 internal override void Write(MetadataWriter mw)
1423 for (int i = 0; i < rowCount; i++)
1425 mw.Write(records[i].PackingSize);
1426 mw.Write(records[i].ClassSize);
1427 mw.WriteTypeDef(records[i].Parent);
1431 protected override int GetRowSize(RowSizeCalc rsc)
1440 sealed class FieldLayoutTable : SortedTable<FieldLayoutTable.Record>
1442 internal const int Index = 0x10;
1444 internal struct Record : ISortKey
1446 internal int Offset;
1451 get { return Field; }
1455 internal override void Read(MetadataReader mr)
1457 for (int i = 0; i < records.Length; i++)
1459 records[i].Offset = mr.ReadInt32();
1460 records[i].Field = mr.ReadField();
1464 internal override void Write(MetadataWriter mw)
1466 for (int i = 0; i < rowCount; i++)
1468 mw.Write(records[i].Offset);
1469 mw.WriteField(records[i].Field);
1473 protected override int GetRowSize(RowSizeCalc rsc)
1481 internal void Fixup(ModuleBuilder moduleBuilder)
1483 for (int i = 0; i < rowCount; i++)
1485 records[i].Field = moduleBuilder.ResolvePseudoToken(records[i].Field);
1491 sealed class StandAloneSigTable : Table<int>
1493 internal const int Index = 0x11;
1495 internal override void Read(MetadataReader mr)
1497 for (int i = 0; i < records.Length; i++)
1499 records[i] = mr.ReadBlobIndex();
1503 internal override void Write(MetadataWriter mw)
1505 for (int i = 0; i < rowCount; i++)
1507 mw.WriteBlobIndex(records[i]);
1511 protected override int GetRowSize(Table.RowSizeCalc rsc)
1513 return rsc.WriteBlobIndex().Value;
1516 internal int FindOrAddRecord(int blob)
1518 for (int i = 0; i < rowCount; i++)
1520 if (records[i] == blob)
1525 return AddRecord(blob);
1529 sealed class EventMapTable : SortedTable<EventMapTable.Record>
1531 internal const int Index = 0x12;
1533 internal struct Record : ISortKey
1535 internal int Parent;
1536 internal int EventList;
1540 get { return Parent; }
1544 internal override void Read(MetadataReader mr)
1546 for (int i = 0; i < records.Length; i++)
1548 records[i].Parent = mr.ReadTypeDef();
1549 records[i].EventList = mr.ReadEvent();
1553 internal override void Write(MetadataWriter mw)
1555 for (int i = 0; i < rowCount; i++)
1557 mw.WriteTypeDef(records[i].Parent);
1558 mw.WriteEvent(records[i].EventList);
1562 protected override int GetRowSize(RowSizeCalc rsc)
1571 sealed class EventPtrTable : Table<int>
1573 internal const int Index = 0x13;
1575 internal override void Read(MetadataReader mr)
1577 for (int i = 0; i < records.Length; i++)
1579 records[i] = mr.ReadEvent();
1584 sealed class EventTable : Table<EventTable.Record>
1586 internal const int Index = 0x14;
1588 internal struct Record
1590 internal short EventFlags;
1592 internal int EventType;
1595 internal override void Read(MetadataReader mr)
1597 for (int i = 0; i < records.Length; i++)
1599 records[i].EventFlags = mr.ReadInt16();
1600 records[i].Name = mr.ReadStringIndex();
1601 records[i].EventType = mr.ReadTypeDefOrRef();
1605 internal override void Write(MetadataWriter mw)
1607 for (int i = 0; i < rowCount; i++)
1609 mw.Write(records[i].EventFlags);
1610 mw.WriteStringIndex(records[i].Name);
1611 mw.WriteTypeDefOrRef(records[i].EventType);
1615 protected override int GetRowSize(RowSizeCalc rsc)
1620 .WriteTypeDefOrRef()
1625 sealed class PropertyMapTable : SortedTable<PropertyMapTable.Record>
1627 internal const int Index = 0x15;
1629 internal struct Record : ISortKey
1631 internal int Parent;
1632 internal int PropertyList;
1636 get { return Parent; }
1640 internal override void Read(MetadataReader mr)
1642 for (int i = 0; i < records.Length; i++)
1644 records[i].Parent = mr.ReadTypeDef();
1645 records[i].PropertyList = mr.ReadProperty();
1649 internal override void Write(MetadataWriter mw)
1651 for (int i = 0; i < rowCount; i++)
1653 mw.WriteTypeDef(records[i].Parent);
1654 mw.WriteProperty(records[i].PropertyList);
1658 protected override int GetRowSize(RowSizeCalc rsc)
1667 sealed class PropertyPtrTable : Table<int>
1669 internal const int Index = 0x16;
1671 internal override void Read(MetadataReader mr)
1673 for (int i = 0; i < records.Length; i++)
1675 records[i] = mr.ReadProperty();
1680 sealed class PropertyTable : Table<PropertyTable.Record>
1682 internal const int Index = 0x17;
1684 internal struct Record
1686 internal short Flags;
1691 internal override void Read(MetadataReader mr)
1693 for (int i = 0; i < records.Length; i++)
1695 records[i].Flags = mr.ReadInt16();
1696 records[i].Name = mr.ReadStringIndex();
1697 records[i].Type = mr.ReadBlobIndex();
1701 internal override void Write(MetadataWriter mw)
1703 for (int i = 0; i < rowCount; i++)
1705 mw.Write(records[i].Flags);
1706 mw.WriteStringIndex(records[i].Name);
1707 mw.WriteBlobIndex(records[i].Type);
1711 protected override int GetRowSize(RowSizeCalc rsc)
1721 sealed class MethodSemanticsTable : SortedTable<MethodSemanticsTable.Record>
1723 internal const int Index = 0x18;
1726 internal const short Setter = 0x0001;
1727 internal const short Getter = 0x0002;
1728 internal const short Other = 0x0004;
1729 internal const short AddOn = 0x0008;
1730 internal const short RemoveOn = 0x0010;
1731 internal const short Fire = 0x0020;
1733 internal struct Record : ISortKey
1735 internal short Semantics;
1736 internal int Method;
1737 internal int Association;
1741 get { return Association; }
1745 internal override void Read(MetadataReader mr)
1747 for (int i = 0; i < records.Length; i++)
1749 records[i].Semantics = mr.ReadInt16();
1750 records[i].Method = mr.ReadMethodDef();
1751 records[i].Association = mr.ReadHasSemantics();
1755 internal override void Write(MetadataWriter mw)
1757 for (int i = 0; i < rowCount; i++)
1759 mw.Write(records[i].Semantics);
1760 mw.WriteMethodDef(records[i].Method);
1761 mw.WriteHasSemantics(records[i].Association);
1765 protected override int GetRowSize(RowSizeCalc rsc)
1770 .WriteHasSemantics()
1774 internal void Fixup(ModuleBuilder moduleBuilder)
1776 for (int i = 0; i < rowCount; i++)
1778 moduleBuilder.FixupPseudoToken(ref records[i].Method);
1779 int token = records[i].Association;
1780 // do the HasSemantics encoding, so that we can sort the table
1781 switch (token >> 24)
1783 case EventTable.Index:
1784 token = (token & 0xFFFFFF) << 1 | 0;
1786 case PropertyTable.Index:
1787 token = (token & 0xFFFFFF) << 1 | 1;
1790 throw new InvalidOperationException();
1792 records[i].Association = token;
1797 internal MethodInfo GetMethod(Module module, int token, bool nonPublic, short semantics)
1799 foreach (int i in Filter(token))
1801 if ((records[i].Semantics & semantics) != 0)
1803 MethodBase method = module.ResolveMethod((MethodDefTable.Index << 24) + records[i].Method);
1804 if (nonPublic || method.IsPublic)
1806 return (MethodInfo)method;
1813 internal MethodInfo[] GetMethods(Module module, int token, bool nonPublic, short semantics)
1815 List<MethodInfo> methods = new List<MethodInfo>();
1816 foreach (int i in Filter(token))
1818 if ((records[i].Semantics & semantics) != 0)
1820 MethodInfo method = (MethodInfo)module.ResolveMethod((MethodDefTable.Index << 24) + records[i].Method);
1821 if (nonPublic || method.IsPublic)
1823 methods.Add(method);
1827 return methods.ToArray();
1830 internal void ComputeFlags(Module module, int token, out bool isPublic, out bool isNonPrivate, out bool isStatic)
1833 isNonPrivate = false;
1835 foreach (int i in Filter(token))
1837 MethodBase method = module.ResolveMethod((MethodDefTable.Index << 24) + records[i].Method);
1838 isPublic |= method.IsPublic;
1839 isNonPrivate |= (method.Attributes & MethodAttributes.MemberAccessMask) > MethodAttributes.Private;
1840 isStatic |= method.IsStatic;
1845 sealed class MethodImplTable : SortedTable<MethodImplTable.Record>
1847 internal const int Index = 0x19;
1849 internal struct Record : ISortKey
1852 internal int MethodBody;
1853 internal int MethodDeclaration;
1857 get { return Class; }
1861 internal override void Read(MetadataReader mr)
1863 for (int i = 0; i < records.Length; i++)
1865 records[i].Class = mr.ReadTypeDef();
1866 records[i].MethodBody = mr.ReadMethodDefOrRef();
1867 records[i].MethodDeclaration = mr.ReadMethodDefOrRef();
1871 internal override void Write(MetadataWriter mw)
1873 for (int i = 0; i < rowCount; i++)
1875 mw.WriteTypeDef(records[i].Class);
1876 mw.WriteMethodDefOrRef(records[i].MethodBody);
1877 mw.WriteMethodDefOrRef(records[i].MethodDeclaration);
1881 protected override int GetRowSize(RowSizeCalc rsc)
1885 .WriteMethodDefOrRef()
1886 .WriteMethodDefOrRef()
1890 internal void Fixup(ModuleBuilder moduleBuilder)
1892 for (int i = 0; i < rowCount; i++)
1894 moduleBuilder.FixupPseudoToken(ref records[i].MethodBody);
1895 moduleBuilder.FixupPseudoToken(ref records[i].MethodDeclaration);
1901 sealed class ModuleRefTable : Table<int>
1903 internal const int Index = 0x1A;
1905 internal override void Read(MetadataReader mr)
1907 for (int i = 0; i < records.Length; i++)
1909 records[i] = mr.ReadStringIndex();
1913 internal override void Write(MetadataWriter mw)
1915 for (int i = 0; i < rowCount; i++)
1917 mw.WriteStringIndex(records[i]);
1921 protected override int GetRowSize(RowSizeCalc rsc)
1928 internal int FindOrAddRecord(int str)
1930 for (int i = 0; i < rowCount; i++)
1932 if (records[i] == str)
1937 return AddRecord(str);
1941 sealed class TypeSpecTable : Table<int>
1943 internal const int Index = 0x1B;
1945 internal override void Read(MetadataReader mr)
1947 for (int i = 0; i < records.Length; i++)
1949 records[i] = mr.ReadBlobIndex();
1953 internal override void Write(MetadataWriter mw)
1955 for (int i = 0; i < rowCount; i++)
1957 mw.WriteBlobIndex(records[i]);
1961 protected override int GetRowSize(Table.RowSizeCalc rsc)
1963 return rsc.WriteBlobIndex().Value;
1967 sealed class ImplMapTable : SortedTable<ImplMapTable.Record>
1969 internal const int Index = 0x1C;
1971 internal struct Record : ISortKey
1973 internal short MappingFlags;
1974 internal int MemberForwarded;
1975 internal int ImportName;
1976 internal int ImportScope;
1980 get { return MemberForwarded; }
1984 internal override void Read(MetadataReader mr)
1986 for (int i = 0; i < records.Length; i++)
1988 records[i].MappingFlags = mr.ReadInt16();
1989 records[i].MemberForwarded = mr.ReadMemberForwarded();
1990 records[i].ImportName = mr.ReadStringIndex();
1991 records[i].ImportScope = mr.ReadModuleRef();
1995 internal override void Write(MetadataWriter mw)
1997 for (int i = 0; i < rowCount; i++)
1999 mw.Write(records[i].MappingFlags);
2000 mw.WriteMemberForwarded(records[i].MemberForwarded);
2001 mw.WriteStringIndex(records[i].ImportName);
2002 mw.WriteModuleRef(records[i].ImportScope);
2006 protected override int GetRowSize(RowSizeCalc rsc)
2010 .WriteMemberForwarded()
2016 internal void Fixup(ModuleBuilder moduleBuilder)
2018 for (int i = 0; i < rowCount; i++)
2020 moduleBuilder.FixupPseudoToken(ref records[i].MemberForwarded);
2026 sealed class FieldRVATable : SortedTable<FieldRVATable.Record>
2028 internal const int Index = 0x1D;
2030 internal struct Record : ISortKey
2032 internal int RVA; // we set the high bit to signify that the RVA is in the CIL stream (instead of .sdata)
2037 get { return Field; }
2041 internal override void Read(MetadataReader mr)
2043 for (int i = 0; i < records.Length; i++)
2045 records[i].RVA = mr.ReadInt32();
2046 records[i].Field = mr.ReadField();
2050 internal override void Write(MetadataWriter mw)
2052 for (int i = 0; i < rowCount; i++)
2054 mw.Write(records[i].RVA);
2055 mw.WriteField(records[i].Field);
2059 protected override int GetRowSize(RowSizeCalc rsc)
2067 internal void Fixup(ModuleBuilder moduleBuilder, int sdataRVA, int cilRVA)
2069 for (int i = 0; i < rowCount; i++)
2071 if (records[i].RVA < 0)
2073 records[i].RVA = (records[i].RVA & 0x7fffffff) + cilRVA;
2077 records[i].RVA += sdataRVA;
2079 moduleBuilder.FixupPseudoToken(ref records[i].Field);
2085 sealed class AssemblyTable : Table<AssemblyTable.Record>
2087 internal const int Index = 0x20;
2089 internal struct Record
2091 internal int HashAlgId;
2092 internal ushort MajorVersion;
2093 internal ushort MinorVersion;
2094 internal ushort BuildNumber;
2095 internal ushort RevisionNumber;
2097 internal int PublicKey;
2099 internal int Culture;
2102 internal override void Read(MetadataReader mr)
2104 for (int i = 0; i < records.Length; i++)
2106 records[i].HashAlgId = mr.ReadInt32();
2107 records[i].MajorVersion = mr.ReadUInt16();
2108 records[i].MinorVersion = mr.ReadUInt16();
2109 records[i].BuildNumber = mr.ReadUInt16();
2110 records[i].RevisionNumber = mr.ReadUInt16();
2111 records[i].Flags = mr.ReadInt32();
2112 records[i].PublicKey = mr.ReadBlobIndex();
2113 records[i].Name = mr.ReadStringIndex();
2114 records[i].Culture = mr.ReadStringIndex();
2118 internal override void Write(MetadataWriter mw)
2120 for (int i = 0; i < rowCount; i++)
2122 mw.Write(records[i].HashAlgId);
2123 mw.Write(records[i].MajorVersion);
2124 mw.Write(records[i].MinorVersion);
2125 mw.Write(records[i].BuildNumber);
2126 mw.Write(records[i].RevisionNumber);
2127 mw.Write(records[i].Flags);
2128 mw.WriteBlobIndex(records[i].PublicKey);
2129 mw.WriteStringIndex(records[i].Name);
2130 mw.WriteStringIndex(records[i].Culture);
2134 protected override int GetRowSize(RowSizeCalc rsc)
2145 sealed class AssemblyRefTable : Table<AssemblyRefTable.Record>
2147 internal const int Index = 0x23;
2149 internal struct Record
2151 internal ushort MajorVersion;
2152 internal ushort MinorVersion;
2153 internal ushort BuildNumber;
2154 internal ushort RevisionNumber;
2156 internal int PublicKeyOrToken;
2158 internal int Culture;
2159 internal int HashValue;
2162 internal int FindOrAddRecord(Record rec)
2164 for (int i = 0; i < rowCount; i++)
2166 // note that we ignore HashValue here!
2167 if (records[i].Name == rec.Name
2168 && records[i].MajorVersion == rec.MajorVersion
2169 && records[i].MinorVersion == rec.MinorVersion
2170 && records[i].BuildNumber == rec.BuildNumber
2171 && records[i].RevisionNumber == rec.RevisionNumber
2172 && records[i].Flags == rec.Flags
2173 && records[i].PublicKeyOrToken == rec.PublicKeyOrToken
2174 && records[i].Culture == rec.Culture
2180 return AddRecord(rec);
2183 internal override void Read(MetadataReader mr)
2185 for (int i = 0; i < records.Length; i++)
2187 records[i].MajorVersion = mr.ReadUInt16();
2188 records[i].MinorVersion = mr.ReadUInt16();
2189 records[i].BuildNumber = mr.ReadUInt16();
2190 records[i].RevisionNumber = mr.ReadUInt16();
2191 records[i].Flags = mr.ReadInt32();
2192 records[i].PublicKeyOrToken = mr.ReadBlobIndex();
2193 records[i].Name = mr.ReadStringIndex();
2194 records[i].Culture = mr.ReadStringIndex();
2195 records[i].HashValue = mr.ReadBlobIndex();
2199 internal override void Write(MetadataWriter mw)
2201 for (int i = 0; i < rowCount; i++)
2203 mw.Write(records[i].MajorVersion);
2204 mw.Write(records[i].MinorVersion);
2205 mw.Write(records[i].BuildNumber);
2206 mw.Write(records[i].RevisionNumber);
2207 mw.Write(records[i].Flags);
2208 mw.WriteBlobIndex(records[i].PublicKeyOrToken);
2209 mw.WriteStringIndex(records[i].Name);
2210 mw.WriteStringIndex(records[i].Culture);
2211 mw.WriteBlobIndex(records[i].HashValue);
2215 protected override int GetRowSize(RowSizeCalc rsc)
2227 sealed class FileTable : Table<FileTable.Record>
2229 internal const int Index = 0x26;
2231 internal struct Record
2235 internal int HashValue;
2238 internal override void Read(MetadataReader mr)
2240 for (int i = 0; i < records.Length; i++)
2242 records[i].Flags = mr.ReadInt32();
2243 records[i].Name = mr.ReadStringIndex();
2244 records[i].HashValue = mr.ReadBlobIndex();
2248 internal override void Write(MetadataWriter mw)
2250 for (int i = 0; i < rowCount; i++)
2252 mw.Write(records[i].Flags);
2253 mw.WriteStringIndex(records[i].Name);
2254 mw.WriteBlobIndex(records[i].HashValue);
2258 protected override int GetRowSize(RowSizeCalc rsc)
2268 sealed class ExportedTypeTable : Table<ExportedTypeTable.Record>
2270 internal const int Index = 0x27;
2272 internal struct Record
2275 internal int TypeDefId;
2276 internal int TypeName;
2277 internal int TypeNamespace;
2278 internal int Implementation;
2281 internal override void Read(MetadataReader mr)
2283 for (int i = 0; i < records.Length; i++)
2285 records[i].Flags = mr.ReadInt32();
2286 records[i].TypeDefId = mr.ReadInt32();
2287 records[i].TypeName = mr.ReadStringIndex();
2288 records[i].TypeNamespace = mr.ReadStringIndex();
2289 records[i].Implementation = mr.ReadImplementation();
2293 internal override void Write(MetadataWriter mw)
2295 for (int i = 0; i < rowCount; i++)
2297 mw.Write(records[i].Flags);
2298 mw.Write(records[i].TypeDefId);
2299 mw.WriteStringIndex(records[i].TypeName);
2300 mw.WriteStringIndex(records[i].TypeNamespace);
2301 mw.WriteImplementation(records[i].Implementation);
2305 protected override int GetRowSize(RowSizeCalc rsc)
2311 .WriteImplementation()
2315 internal int FindOrAddRecord(Record rec)
2317 for (int i = 0; i < rowCount; i++)
2319 if (records[i].Implementation == rec.Implementation
2320 && records[i].TypeName == rec.TypeName
2321 && records[i].TypeNamespace == rec.TypeNamespace)
2326 return AddRecord(rec);
2329 internal void Fixup(ModuleBuilder moduleBuilder)
2331 for (int i = 0; i < rowCount; i++)
2333 moduleBuilder.FixupPseudoToken(ref records[i].Implementation);
2338 sealed class ManifestResourceTable : Table<ManifestResourceTable.Record>
2340 internal const int Index = 0x28;
2342 internal struct Record
2344 internal int Offset;
2347 internal int Implementation;
2350 internal override void Read(MetadataReader mr)
2352 for (int i = 0; i < records.Length; i++)
2354 records[i].Offset = mr.ReadInt32();
2355 records[i].Flags = mr.ReadInt32();
2356 records[i].Name = mr.ReadStringIndex();
2357 records[i].Implementation = mr.ReadImplementation();
2361 internal override void Write(MetadataWriter mw)
2363 for (int i = 0; i < rowCount; i++)
2365 mw.Write(records[i].Offset);
2366 mw.Write(records[i].Flags);
2367 mw.WriteStringIndex(records[i].Name);
2368 mw.WriteImplementation(records[i].Implementation);
2372 protected override int GetRowSize(RowSizeCalc rsc)
2377 .WriteImplementation()
2381 internal void Fixup(ModuleBuilder moduleBuilder)
2383 for (int i = 0; i < rowCount; i++)
2385 moduleBuilder.FixupPseudoToken(ref records[i].Implementation);
2390 sealed class NestedClassTable : SortedTable<NestedClassTable.Record>
2392 internal const int Index = 0x29;
2394 internal struct Record : ISortKey
2396 internal int NestedClass;
2397 internal int EnclosingClass;
2401 get { return NestedClass; }
2405 internal override void Read(MetadataReader mr)
2407 for (int i = 0; i < records.Length; i++)
2409 records[i].NestedClass = mr.ReadTypeDef();
2410 records[i].EnclosingClass = mr.ReadTypeDef();
2414 internal override void Write(MetadataWriter mw)
2416 for (int i = 0; i < rowCount; i++)
2418 mw.WriteTypeDef(records[i].NestedClass);
2419 mw.WriteTypeDef(records[i].EnclosingClass);
2423 protected override int GetRowSize(RowSizeCalc rsc)
2431 internal List<int> GetNestedClasses(int enclosingClass)
2433 List<int> nestedClasses = new List<int>();
2434 for (int i = 0; i < rowCount; i++)
2436 if (records[i].EnclosingClass == enclosingClass)
2438 nestedClasses.Add(records[i].NestedClass);
2441 return nestedClasses;
2445 sealed class GenericParamTable : SortedTable<GenericParamTable.Record>, IComparer<GenericParamTable.Record>
2447 internal const int Index = 0x2A;
2449 internal struct Record : ISortKey
2451 internal short Number;
2452 internal short Flags;
2455 // not part of the table, we use it to be able to fixup the GenericParamConstraint table
2456 internal int unsortedIndex;
2460 get { return Owner; }
2464 internal override void Read(MetadataReader mr)
2466 for (int i = 0; i < records.Length; i++)
2468 records[i].Number = mr.ReadInt16();
2469 records[i].Flags = mr.ReadInt16();
2470 records[i].Owner = mr.ReadTypeOrMethodDef();
2471 records[i].Name = mr.ReadStringIndex();
2475 internal override void Write(MetadataWriter mw)
2477 for (int i = 0; i < rowCount; i++)
2479 mw.Write(records[i].Number);
2480 mw.Write(records[i].Flags);
2481 mw.WriteTypeOrMethodDef(records[i].Owner);
2482 mw.WriteStringIndex(records[i].Name);
2486 protected override int GetRowSize(RowSizeCalc rsc)
2490 .WriteTypeOrMethodDef()
2495 internal void Fixup(ModuleBuilder moduleBuilder)
2497 for (int i = 0; i < rowCount; i++)
2499 int token = records[i].Owner;
2500 moduleBuilder.FixupPseudoToken(ref token);
2501 // do the TypeOrMethodDef encoding, so that we can sort the table
2502 switch (token >> 24)
2504 case TypeDefTable.Index:
2505 records[i].Owner = (token & 0xFFFFFF) << 1 | 0;
2507 case MethodDefTable.Index:
2508 records[i].Owner = (token & 0xFFFFFF) << 1 | 1;
2511 throw new InvalidOperationException();
2513 records[i].unsortedIndex = i;
2515 // FXBUG the unnecessary (IComparer<Record>) cast is a workaround for a .NET 2.0 C# compiler bug
2516 Array.Sort(records, 0, rowCount, (IComparer<Record>)this);
2519 int IComparer<Record>.Compare(Record x, Record y)
2521 if (x.Owner == y.Owner)
2523 return x.Number == y.Number ? 0 : (x.Number > y.Number ? 1 : -1);
2525 return x.Owner > y.Owner ? 1 : -1;
2528 internal void PatchAttribute(int token, GenericParameterAttributes genericParameterAttributes)
2530 records[(token & 0xFFFFFF) - 1].Flags = (short)genericParameterAttributes;
2533 internal int[] GetIndexFixup()
2535 int[] array = new int[rowCount];
2536 for (int i = 0; i < rowCount; i++)
2538 array[records[i].unsortedIndex] = i;
2543 internal int FindFirstByOwner(int token)
2545 foreach (int i in Filter(token))
2553 sealed class MethodSpecTable : Table<MethodSpecTable.Record>
2555 internal const int Index = 0x2B;
2557 internal struct Record
2559 internal int Method;
2560 internal int Instantiation;
2563 internal override void Read(MetadataReader mr)
2565 for (int i = 0; i < records.Length; i++)
2567 records[i].Method = mr.ReadMethodDefOrRef();
2568 records[i].Instantiation = mr.ReadBlobIndex();
2572 internal override void Write(MetadataWriter mw)
2574 for (int i = 0; i < rowCount; i++)
2576 mw.WriteMethodDefOrRef(records[i].Method);
2577 mw.WriteBlobIndex(records[i].Instantiation);
2581 protected override int GetRowSize(RowSizeCalc rsc)
2584 .WriteMethodDefOrRef()
2589 internal int FindOrAddRecord(Record record)
2591 for (int i = 0; i < rowCount; i++)
2593 if (records[i].Method == record.Method
2594 && records[i].Instantiation == record.Instantiation)
2599 return AddRecord(record);
2602 internal void Fixup(ModuleBuilder moduleBuilder)
2604 for (int i = 0; i < rowCount; i++)
2606 moduleBuilder.FixupPseudoToken(ref records[i].Method);
2611 sealed class GenericParamConstraintTable : SortedTable<GenericParamConstraintTable.Record>
2613 internal const int Index = 0x2C;
2615 internal struct Record : ISortKey
2618 internal int Constraint;
2622 get { return Owner; }
2626 internal override void Read(MetadataReader mr)
2628 for (int i = 0; i < records.Length; i++)
2630 records[i].Owner = mr.ReadGenericParam();
2631 records[i].Constraint = mr.ReadTypeDefOrRef();
2635 internal override void Write(MetadataWriter mw)
2637 for (int i = 0; i < rowCount; i++)
2639 mw.WriteGenericParam(records[i].Owner);
2640 mw.WriteTypeDefOrRef(records[i].Constraint);
2644 protected override int GetRowSize(RowSizeCalc rsc)
2647 .WriteGenericParam()
2648 .WriteTypeDefOrRef()
2652 internal void Fixup(ModuleBuilder moduleBuilder)
2654 int[] fixups = moduleBuilder.GenericParam.GetIndexFixup();
2655 for (int i = 0; i < rowCount; i++)
2657 records[i].Owner = fixups[records[i].Owner - 1] + 1;