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 private struct OrdinalWrapper
430 internal int ordinal;
434 protected void Sort(IComparer<T> comparer)
436 OrdinalWrapper[] items = new OrdinalWrapper[rowCount];
437 for (int i = 0; i < items.Length; i++)
439 items[i].ordinal = i;
440 items[i].value = records[i];
442 Array.Sort(items, delegate(OrdinalWrapper x, OrdinalWrapper y)
444 int res = comparer.Compare(x.value, y.value);
447 res = x.ordinal.CompareTo(y.ordinal);
451 for (int i = 0; i < items.Length; i++)
453 records[i] = items[i].value;
457 protected void Sort(IComparer<T> comparer)
459 Array.Sort(records, 0, rowCount, comparer);
464 abstract class SortedTable<T> : Table<T>
465 where T : SortedTable<T>.ISortKey
467 internal interface ISortKey
472 internal struct Enumerable
474 private readonly SortedTable<T> table;
475 private readonly int token;
477 internal Enumerable(SortedTable<T> table, int token)
483 public Enumerator GetEnumerator()
485 T[] records = table.records;
488 return new Enumerator(records, table.RowCount - 1, -1, token);
490 int index = BinarySearch(records, table.RowCount, token & 0xFFFFFF);
493 return new Enumerator(null, 0, 1, -1);
496 while (start > 0 && (records[start - 1].Key & 0xFFFFFF) == (token & 0xFFFFFF))
501 int max = table.RowCount - 1;
502 while (end < max && (records[end + 1].Key & 0xFFFFFF) == (token & 0xFFFFFF))
506 return new Enumerator(records, end, start - 1, token);
509 private static int BinarySearch(T[] records, int length, int maskedToken)
512 int max = length - 1;
515 int mid = min + ((max - min) / 2);
516 int maskedValue = records[mid].Key & 0xFFFFFF;
517 if (maskedToken == maskedValue)
521 else if (maskedToken < maskedValue)
534 internal struct Enumerator
536 private readonly T[] records;
537 private readonly int token;
538 private readonly int max;
541 internal Enumerator(T[] records, int max, int index, int token)
543 this.records = records;
551 get { return index; }
554 public bool MoveNext()
559 if (records[index].Key == token)
568 internal Enumerable Filter(int token)
570 return new Enumerable(this, token);
574 sealed class ModuleTable : Table<ModuleTable.Record>
576 internal const int Index = 0x00;
578 internal struct Record
580 internal short Generation;
581 internal int Name; // -> StringHeap
582 internal int Mvid; // -> GuidHeap
583 internal int EncId; // -> GuidHeap
584 internal int EncBaseId; // -> GuidHeap
587 internal override void Read(MetadataReader mr)
589 for (int i = 0; i < records.Length; i++)
591 records[i].Generation = mr.ReadInt16();
592 records[i].Name = mr.ReadStringIndex();
593 records[i].Mvid = mr.ReadGuidIndex();
594 records[i].EncId = mr.ReadGuidIndex();
595 records[i].EncBaseId = mr.ReadGuidIndex();
599 internal override void Write(MetadataWriter mw)
601 for (int i = 0; i < rowCount; i++)
603 mw.Write(records[i].Generation);
604 mw.WriteStringIndex(records[i].Name);
605 mw.WriteGuidIndex(records[i].Mvid);
606 mw.WriteGuidIndex(records[i].EncId);
607 mw.WriteGuidIndex(records[i].EncBaseId);
611 protected override int GetRowSize(RowSizeCalc rsc)
622 internal void Add(short generation, int name, int mvid, int encid, int encbaseid)
624 Record record = new Record();
625 record.Generation = generation;
628 record.EncId = encid;
629 record.EncBaseId = encbaseid;
634 sealed class TypeRefTable : Table<TypeRefTable.Record>
636 internal const int Index = 0x01;
638 internal struct Record
640 internal int ResolutionScope;
641 internal int TypeName;
642 internal int TypeNameSpace;
645 internal override void Read(MetadataReader mr)
647 for (int i = 0; i < records.Length; i++)
649 records[i].ResolutionScope = mr.ReadResolutionScope();
650 records[i].TypeName = mr.ReadStringIndex();
651 records[i].TypeNameSpace = mr.ReadStringIndex();
655 internal override void Write(MetadataWriter mw)
657 for (int i = 0; i < rowCount; i++)
659 mw.WriteResolutionScope(records[i].ResolutionScope);
660 mw.WriteStringIndex(records[i].TypeName);
661 mw.WriteStringIndex(records[i].TypeNameSpace);
665 protected override int GetRowSize(RowSizeCalc rsc)
668 .WriteResolutionScope()
675 sealed class TypeDefTable : Table<TypeDefTable.Record>
677 internal const int Index = 0x02;
679 internal struct Record
682 internal int TypeName;
683 internal int TypeNamespace;
684 internal int Extends;
685 internal int FieldList;
686 internal int MethodList;
689 internal override void Read(MetadataReader mr)
691 for (int i = 0; i < records.Length; i++)
693 records[i].Flags = mr.ReadInt32();
694 records[i].TypeName = mr.ReadStringIndex();
695 records[i].TypeNamespace = mr.ReadStringIndex();
696 records[i].Extends = mr.ReadTypeDefOrRef();
697 records[i].FieldList = mr.ReadField();
698 records[i].MethodList = mr.ReadMethodDef();
702 internal override void Write(MetadataWriter mw)
704 mw.ModuleBuilder.WriteTypeDefTable(mw);
707 internal int AllocToken()
709 return 0x02000000 + AddVirtualRecord();
712 protected override int GetRowSize(RowSizeCalc rsc)
725 sealed class FieldPtrTable : Table<int>
727 internal const int Index = 0x03;
729 internal override void Read(MetadataReader mr)
731 for (int i = 0; i < records.Length; i++)
733 records[i] = mr.ReadField();
738 sealed class FieldTable : Table<FieldTable.Record>
740 internal const int Index = 0x04;
742 internal struct Record
744 internal short Flags;
746 internal int Signature;
749 internal override void Read(MetadataReader mr)
751 for (int i = 0; i < records.Length; i++)
753 records[i].Flags = mr.ReadInt16();
754 records[i].Name = mr.ReadStringIndex();
755 records[i].Signature = mr.ReadBlobIndex();
759 internal override void Write(MetadataWriter mw)
761 mw.ModuleBuilder.WriteFieldTable(mw);
764 protected override int GetRowSize(RowSizeCalc rsc)
774 sealed class MethodPtrTable : Table<int>
776 internal const int Index = 0x05;
778 internal override void Read(MetadataReader mr)
780 for (int i = 0; i < records.Length; i++)
782 records[i] = mr.ReadMethodDef();
787 sealed class MethodDefTable : Table<MethodDefTable.Record>
789 internal const int Index = 0x06;
792 internal struct Record
795 internal short ImplFlags;
796 internal short Flags;
798 internal int Signature;
799 internal int ParamList;
802 internal override void Read(MetadataReader mr)
804 for (int i = 0; i < records.Length; i++)
806 records[i].RVA = mr.ReadInt32();
807 records[i].ImplFlags = mr.ReadInt16();
808 records[i].Flags = mr.ReadInt16();
809 records[i].Name = mr.ReadStringIndex();
810 records[i].Signature = mr.ReadBlobIndex();
811 records[i].ParamList = mr.ReadParam();
815 internal override void Write(MetadataWriter mw)
817 mw.ModuleBuilder.WriteMethodDefTable(baseRVA, mw);
820 protected override int GetRowSize(RowSizeCalc rsc)
830 internal void Fixup(TextSection code)
832 baseRVA = (int)code.MethodBodiesRVA;
836 sealed class ParamPtrTable : Table<int>
838 internal const int Index = 0x07;
840 internal override void Read(MetadataReader mr)
842 for (int i = 0; i < records.Length; i++)
844 records[i] = mr.ReadParam();
849 sealed class ParamTable : Table<ParamTable.Record>
851 internal const int Index = 0x08;
853 internal struct Record
855 internal short Flags;
856 internal short Sequence;
860 internal override void Read(MetadataReader mr)
862 for (int i = 0; i < records.Length; i++)
864 records[i].Flags = mr.ReadInt16();
865 records[i].Sequence = mr.ReadInt16();
866 records[i].Name = mr.ReadStringIndex();
870 internal override void Write(MetadataWriter mw)
872 mw.ModuleBuilder.WriteParamTable(mw);
875 protected override int GetRowSize(RowSizeCalc rsc)
884 sealed class InterfaceImplTable : SortedTable<InterfaceImplTable.Record>, IComparer<InterfaceImplTable.Record>
886 internal const int Index = 0x09;
888 internal struct Record : ISortKey
891 internal int Interface;
895 get { return Class; }
899 internal override void Read(MetadataReader mr)
901 for (int i = 0; i < records.Length; i++)
903 records[i].Class = mr.ReadTypeDef();
904 records[i].Interface = mr.ReadTypeDefOrRef();
908 internal override void Write(MetadataWriter mw)
910 for (int i = 0; i < rowCount; i++)
912 mw.WriteTypeDef(records[i].Class);
913 mw.WriteEncodedTypeDefOrRef(records[i].Interface);
917 protected override int GetRowSize(RowSizeCalc rsc)
925 internal void Fixup()
927 for (int i = 0; i < rowCount; i++)
929 int token = records[i].Interface;
934 case TypeDefTable.Index:
935 token = (token & 0xFFFFFF) << 2 | 0;
937 case TypeRefTable.Index:
938 token = (token & 0xFFFFFF) << 2 | 1;
940 case TypeSpecTable.Index:
941 token = (token & 0xFFFFFF) << 2 | 2;
944 throw new InvalidOperationException();
946 records[i].Interface = token;
951 int IComparer<Record>.Compare(Record x, Record y)
953 if (x.Class == y.Class)
958 // LAMESPEC the CLI spec says that InterfaceImpl should be sorted by { Class, Interface }, but it appears to be
959 // only necessary to sort by Class.
960 return x.Interface == y.Interface ? 0 : (x.Interface > y.Interface ? 1 : -1);
963 return x.Class > y.Class ? 1 : -1;
967 sealed class MemberRefTable : Table<MemberRefTable.Record>
969 internal const int Index = 0x0A;
971 internal struct Record
975 internal int Signature;
978 internal override void Read(MetadataReader mr)
980 for (int i = 0; i < records.Length; i++)
982 records[i].Class = mr.ReadMemberRefParent();
983 records[i].Name = mr.ReadStringIndex();
984 records[i].Signature = mr.ReadBlobIndex();
988 internal override void Write(MetadataWriter mw)
990 for (int i = 0; i < rowCount; i++)
992 mw.WriteMemberRefParent(records[i].Class);
993 mw.WriteStringIndex(records[i].Name);
994 mw.WriteBlobIndex(records[i].Signature);
998 protected override int GetRowSize(RowSizeCalc rsc)
1001 .WriteMemberRefParent()
1007 internal int FindOrAddRecord(Record record)
1009 for (int i = 0; i < rowCount; i++)
1011 if (records[i].Class == record.Class
1012 && records[i].Name == record.Name
1013 && records[i].Signature == record.Signature)
1018 return AddRecord(record);
1021 internal void Fixup(ModuleBuilder moduleBuilder)
1023 for (int i = 0; i < rowCount; i++)
1025 if (moduleBuilder.IsPseudoToken(records[i].Class))
1027 records[i].Class = moduleBuilder.ResolvePseudoToken(records[i].Class);
1033 sealed class ConstantTable : SortedTable<ConstantTable.Record>, IComparer<ConstantTable.Record>
1035 internal const int Index = 0x0B;
1037 internal struct Record : ISortKey
1039 internal short Type;
1040 internal int Parent;
1045 get { return Parent; }
1049 internal override void Read(MetadataReader mr)
1051 for (int i = 0; i < records.Length; i++)
1053 records[i].Type = mr.ReadInt16();
1054 records[i].Parent = mr.ReadHasConstant();
1055 records[i].Value = mr.ReadBlobIndex();
1059 internal override void Write(MetadataWriter mw)
1061 for (int i = 0; i < rowCount; i++)
1063 mw.Write(records[i].Type);
1064 mw.WriteHasConstant(records[i].Parent);
1065 mw.WriteBlobIndex(records[i].Value);
1069 protected override int GetRowSize(RowSizeCalc rsc)
1078 internal void Fixup(ModuleBuilder moduleBuilder)
1080 for (int i = 0; i < rowCount; i++)
1082 int token = records[i].Parent;
1083 if (moduleBuilder.IsPseudoToken(token))
1085 token = moduleBuilder.ResolvePseudoToken(token);
1087 // do the HasConstant encoding, so that we can sort the table
1088 switch (token >> 24)
1090 case FieldTable.Index:
1091 records[i].Parent = (token & 0xFFFFFF) << 2 | 0;
1093 case ParamTable.Index:
1094 records[i].Parent = (token & 0xFFFFFF) << 2 | 1;
1096 case PropertyTable.Index:
1097 records[i].Parent = (token & 0xFFFFFF) << 2 | 2;
1100 throw new InvalidOperationException();
1103 Array.Sort(records, 0, rowCount, this);
1106 int IComparer<Record>.Compare(Record x, Record y)
1108 return x.Parent == y.Parent ? 0 : (x.Parent > y.Parent ? 1 : -1);
1111 internal object GetRawConstantValue(Module module, int parent)
1113 foreach (int i in Filter(parent))
1115 ByteReader br = module.GetBlob(module.Constant.records[i].Value);
1116 switch (module.Constant.records[i].Type)
1118 // see ModuleBuilder.AddConstant for the encodings
1119 case Signature.ELEMENT_TYPE_BOOLEAN:
1120 return br.ReadByte() != 0;
1121 case Signature.ELEMENT_TYPE_I1:
1122 return br.ReadSByte();
1123 case Signature.ELEMENT_TYPE_I2:
1124 return br.ReadInt16();
1125 case Signature.ELEMENT_TYPE_I4:
1126 return br.ReadInt32();
1127 case Signature.ELEMENT_TYPE_I8:
1128 return br.ReadInt64();
1129 case Signature.ELEMENT_TYPE_U1:
1130 return br.ReadByte();
1131 case Signature.ELEMENT_TYPE_U2:
1132 return br.ReadUInt16();
1133 case Signature.ELEMENT_TYPE_U4:
1134 return br.ReadUInt32();
1135 case Signature.ELEMENT_TYPE_U8:
1136 return br.ReadUInt64();
1137 case Signature.ELEMENT_TYPE_R4:
1138 return br.ReadSingle();
1139 case Signature.ELEMENT_TYPE_R8:
1140 return br.ReadDouble();
1141 case Signature.ELEMENT_TYPE_CHAR:
1142 return br.ReadChar();
1143 case Signature.ELEMENT_TYPE_STRING:
1145 char[] chars = new char[br.Length / 2];
1146 for (int j = 0; j < chars.Length; j++)
1148 chars[j] = br.ReadChar();
1150 return new String(chars);
1152 case Signature.ELEMENT_TYPE_CLASS:
1153 if (br.ReadInt32() != 0)
1155 throw new BadImageFormatException();
1159 throw new BadImageFormatException();
1162 throw new InvalidOperationException();
1166 sealed class CustomAttributeTable : SortedTable<CustomAttributeTable.Record>, IComparer<CustomAttributeTable.Record>
1168 internal const int Index = 0x0C;
1170 internal struct Record : ISortKey
1172 internal int Parent;
1178 get { return Parent; }
1182 internal override void Read(MetadataReader mr)
1184 for (int i = 0; i < records.Length; i++)
1186 records[i].Parent = mr.ReadHasCustomAttribute();
1187 records[i].Type = mr.ReadCustomAttributeType();
1188 records[i].Value = mr.ReadBlobIndex();
1192 internal override void Write(MetadataWriter mw)
1194 for (int i = 0; i < rowCount; i++)
1196 mw.WriteHasCustomAttribute(records[i].Parent);
1197 mw.WriteCustomAttributeType(records[i].Type);
1198 mw.WriteBlobIndex(records[i].Value);
1202 protected override int GetRowSize(RowSizeCalc rsc)
1205 .WriteHasCustomAttribute()
1206 .WriteCustomAttributeType()
1211 internal void Fixup(ModuleBuilder moduleBuilder)
1213 int[] genericParamFixup = moduleBuilder.GenericParam.GetIndexFixup();
1214 for (int i = 0; i < rowCount; i++)
1216 if (moduleBuilder.IsPseudoToken(records[i].Type))
1218 records[i].Type = moduleBuilder.ResolvePseudoToken(records[i].Type);
1220 int token = records[i].Parent;
1221 if (moduleBuilder.IsPseudoToken(token))
1223 token = moduleBuilder.ResolvePseudoToken(token);
1225 // do the HasCustomAttribute encoding, so that we can sort the table
1226 switch (token >> 24)
1228 case MethodDefTable.Index:
1229 records[i].Parent = (token & 0xFFFFFF) << 5 | 0;
1231 case FieldTable.Index:
1232 records[i].Parent = (token & 0xFFFFFF) << 5 | 1;
1234 case TypeRefTable.Index:
1235 records[i].Parent = (token & 0xFFFFFF) << 5 | 2;
1237 case TypeDefTable.Index:
1238 records[i].Parent = (token & 0xFFFFFF) << 5 | 3;
1240 case ParamTable.Index:
1241 records[i].Parent = (token & 0xFFFFFF) << 5 | 4;
1243 case InterfaceImplTable.Index:
1244 records[i].Parent = (token & 0xFFFFFF) << 5 | 5;
1246 case MemberRefTable.Index:
1247 records[i].Parent = (token & 0xFFFFFF) << 5 | 6;
1249 case ModuleTable.Index:
1250 records[i].Parent = (token & 0xFFFFFF) << 5 | 7;
1252 // Permission (8) table doesn't exist in the spec
1253 case PropertyTable.Index:
1254 records[i].Parent = (token & 0xFFFFFF) << 5 | 9;
1256 case EventTable.Index:
1257 records[i].Parent = (token & 0xFFFFFF) << 5 | 10;
1259 case StandAloneSigTable.Index:
1260 records[i].Parent = (token & 0xFFFFFF) << 5 | 11;
1262 case ModuleRefTable.Index:
1263 records[i].Parent = (token & 0xFFFFFF) << 5 | 12;
1265 case TypeSpecTable.Index:
1266 records[i].Parent = (token & 0xFFFFFF) << 5 | 13;
1268 case AssemblyTable.Index:
1269 records[i].Parent = (token & 0xFFFFFF) << 5 | 14;
1271 case AssemblyRefTable.Index:
1272 records[i].Parent = (token & 0xFFFFFF) << 5 | 15;
1274 case FileTable.Index:
1275 records[i].Parent = (token & 0xFFFFFF) << 5 | 16;
1277 case ExportedTypeTable.Index:
1278 records[i].Parent = (token & 0xFFFFFF) << 5 | 17;
1280 case ManifestResourceTable.Index:
1281 records[i].Parent = (token & 0xFFFFFF) << 5 | 18;
1283 case GenericParamTable.Index:
1284 records[i].Parent = (genericParamFixup[(token & 0xFFFFFF) - 1] + 1) << 5 | 19;
1287 throw new InvalidOperationException();
1293 int IComparer<Record>.Compare(Record x, Record y)
1295 return x.Parent == y.Parent ? 0 : (x.Parent > y.Parent ? 1 : -1);
1299 sealed class FieldMarshalTable : SortedTable<FieldMarshalTable.Record>, IComparer<FieldMarshalTable.Record>
1301 internal const int Index = 0x0D;
1303 internal struct Record : ISortKey
1305 internal int Parent;
1306 internal int NativeType;
1310 get { return Parent; }
1314 internal override void Read(MetadataReader mr)
1316 for (int i = 0; i < records.Length; i++)
1318 records[i].Parent = mr.ReadHasFieldMarshal();
1319 records[i].NativeType = mr.ReadBlobIndex();
1323 internal override void Write(MetadataWriter mw)
1325 for (int i = 0; i < rowCount; i++)
1327 mw.WriteHasFieldMarshal(records[i].Parent);
1328 mw.WriteBlobIndex(records[i].NativeType);
1332 protected override int GetRowSize(RowSizeCalc rsc)
1335 .WriteHasFieldMarshal()
1340 internal void Fixup(ModuleBuilder moduleBuilder)
1342 for (int i = 0; i < rowCount; i++)
1344 int token = moduleBuilder.ResolvePseudoToken(records[i].Parent);
1345 // do the HasFieldMarshal encoding, so that we can sort the table
1346 switch (token >> 24)
1348 case FieldTable.Index:
1349 records[i].Parent = (token & 0xFFFFFF) << 1 | 0;
1351 case ParamTable.Index:
1352 records[i].Parent = (token & 0xFFFFFF) << 1 | 1;
1355 throw new InvalidOperationException();
1358 Array.Sort(records, 0, rowCount, this);
1361 int IComparer<Record>.Compare(Record x, Record y)
1363 return x.Parent == y.Parent ? 0 : (x.Parent > y.Parent ? 1 : -1);
1367 sealed class DeclSecurityTable : SortedTable<DeclSecurityTable.Record>, IComparer<DeclSecurityTable.Record>
1369 internal const int Index = 0x0E;
1371 internal struct Record : ISortKey
1373 internal short Action;
1374 internal int Parent;
1375 internal int PermissionSet;
1379 get { return Parent; }
1383 internal override void Read(MetadataReader mr)
1385 for (int i = 0; i < records.Length; i++)
1387 records[i].Action = mr.ReadInt16();
1388 records[i].Parent = mr.ReadHasDeclSecurity();
1389 records[i].PermissionSet = mr.ReadBlobIndex();
1393 internal override void Write(MetadataWriter mw)
1395 for (int i = 0; i < rowCount; i++)
1397 mw.Write(records[i].Action);
1398 mw.WriteHasDeclSecurity(records[i].Parent);
1399 mw.WriteBlobIndex(records[i].PermissionSet);
1403 protected override int GetRowSize(RowSizeCalc rsc)
1407 .WriteHasDeclSecurity()
1412 internal void Fixup(ModuleBuilder moduleBuilder)
1414 for (int i = 0; i < rowCount; i++)
1416 int token = records[i].Parent;
1417 if (moduleBuilder.IsPseudoToken(token))
1419 token = moduleBuilder.ResolvePseudoToken(token);
1421 // do the HasDeclSecurity encoding, so that we can sort the table
1422 switch (token >> 24)
1424 case TypeDefTable.Index:
1425 token = (token & 0xFFFFFF) << 2 | 0;
1427 case MethodDefTable.Index:
1428 token = (token & 0xFFFFFF) << 2 | 1;
1430 case AssemblyTable.Index:
1431 token = (token & 0xFFFFFF) << 2 | 2;
1434 throw new InvalidOperationException();
1436 records[i].Parent = token;
1441 int IComparer<Record>.Compare(Record x, Record y)
1443 return x.Parent == y.Parent ? 0 : (x.Parent > y.Parent ? 1 : -1);
1447 sealed class ClassLayoutTable : SortedTable<ClassLayoutTable.Record>, IComparer<ClassLayoutTable.Record>
1449 internal const int Index = 0x0f;
1451 internal struct Record : ISortKey
1453 internal short PackingSize;
1454 internal int ClassSize;
1455 internal int Parent;
1459 get { return Parent; }
1463 internal override void Read(MetadataReader mr)
1465 for (int i = 0; i < records.Length; i++)
1467 records[i].PackingSize = mr.ReadInt16();
1468 records[i].ClassSize = mr.ReadInt32();
1469 records[i].Parent = mr.ReadTypeDef();
1473 internal override void Write(MetadataWriter mw)
1475 Array.Sort(records, 0, rowCount, this);
1476 for (int i = 0; i < rowCount; i++)
1478 mw.Write(records[i].PackingSize);
1479 mw.Write(records[i].ClassSize);
1480 mw.WriteTypeDef(records[i].Parent);
1484 protected override int GetRowSize(RowSizeCalc rsc)
1492 int IComparer<Record>.Compare(Record x, Record y)
1494 return x.Parent == y.Parent ? 0 : (x.Parent > y.Parent ? 1 : -1);
1498 sealed class FieldLayoutTable : SortedTable<FieldLayoutTable.Record>, IComparer<FieldLayoutTable.Record>
1500 internal const int Index = 0x10;
1502 internal struct Record : ISortKey
1504 internal int Offset;
1509 get { return Field; }
1513 internal override void Read(MetadataReader mr)
1515 for (int i = 0; i < records.Length; i++)
1517 records[i].Offset = mr.ReadInt32();
1518 records[i].Field = mr.ReadField();
1522 internal override void Write(MetadataWriter mw)
1524 for (int i = 0; i < rowCount; i++)
1526 mw.Write(records[i].Offset);
1527 mw.WriteField(records[i].Field);
1531 protected override int GetRowSize(RowSizeCalc rsc)
1539 internal void Fixup(ModuleBuilder moduleBuilder)
1541 for (int i = 0; i < rowCount; i++)
1543 records[i].Field = moduleBuilder.ResolvePseudoToken(records[i].Field);
1545 Array.Sort(records, 0, rowCount, this);
1548 int IComparer<Record>.Compare(Record x, Record y)
1550 return x.Field == y.Field ? 0 : (x.Field > y.Field ? 1 : -1);
1554 sealed class StandAloneSigTable : Table<int>
1556 internal const int Index = 0x11;
1558 internal override void Read(MetadataReader mr)
1560 for (int i = 0; i < records.Length; i++)
1562 records[i] = mr.ReadBlobIndex();
1566 internal override void Write(MetadataWriter mw)
1568 for (int i = 0; i < rowCount; i++)
1570 mw.WriteBlobIndex(records[i]);
1574 protected override int GetRowSize(Table.RowSizeCalc rsc)
1576 return rsc.WriteBlobIndex().Value;
1579 internal int FindOrAddRecord(int blob)
1581 for (int i = 0; i < rowCount; i++)
1583 if (records[i] == blob)
1588 return AddRecord(blob);
1592 sealed class EventMapTable : SortedTable<EventMapTable.Record>
1594 internal const int Index = 0x12;
1596 internal struct Record : ISortKey
1598 internal int Parent;
1599 internal int EventList;
1603 get { return Parent; }
1607 internal override void Read(MetadataReader mr)
1609 for (int i = 0; i < records.Length; i++)
1611 records[i].Parent = mr.ReadTypeDef();
1612 records[i].EventList = mr.ReadEvent();
1616 internal override void Write(MetadataWriter mw)
1618 for (int i = 0; i < rowCount; i++)
1620 mw.WriteTypeDef(records[i].Parent);
1621 mw.WriteEvent(records[i].EventList);
1625 protected override int GetRowSize(RowSizeCalc rsc)
1634 sealed class EventPtrTable : Table<int>
1636 internal const int Index = 0x13;
1638 internal override void Read(MetadataReader mr)
1640 for (int i = 0; i < records.Length; i++)
1642 records[i] = mr.ReadEvent();
1647 sealed class EventTable : Table<EventTable.Record>
1649 internal const int Index = 0x14;
1651 internal struct Record
1653 internal short EventFlags;
1655 internal int EventType;
1658 internal override void Read(MetadataReader mr)
1660 for (int i = 0; i < records.Length; i++)
1662 records[i].EventFlags = mr.ReadInt16();
1663 records[i].Name = mr.ReadStringIndex();
1664 records[i].EventType = mr.ReadTypeDefOrRef();
1668 internal override void Write(MetadataWriter mw)
1670 for (int i = 0; i < rowCount; i++)
1672 mw.Write(records[i].EventFlags);
1673 mw.WriteStringIndex(records[i].Name);
1674 mw.WriteTypeDefOrRef(records[i].EventType);
1678 protected override int GetRowSize(RowSizeCalc rsc)
1683 .WriteTypeDefOrRef()
1688 sealed class PropertyMapTable : SortedTable<PropertyMapTable.Record>
1690 internal const int Index = 0x15;
1692 internal struct Record : ISortKey
1694 internal int Parent;
1695 internal int PropertyList;
1699 get { return Parent; }
1703 internal override void Read(MetadataReader mr)
1705 for (int i = 0; i < records.Length; i++)
1707 records[i].Parent = mr.ReadTypeDef();
1708 records[i].PropertyList = mr.ReadProperty();
1712 internal override void Write(MetadataWriter mw)
1714 for (int i = 0; i < rowCount; i++)
1716 mw.WriteTypeDef(records[i].Parent);
1717 mw.WriteProperty(records[i].PropertyList);
1721 protected override int GetRowSize(RowSizeCalc rsc)
1730 sealed class PropertyPtrTable : Table<int>
1732 internal const int Index = 0x16;
1734 internal override void Read(MetadataReader mr)
1736 for (int i = 0; i < records.Length; i++)
1738 records[i] = mr.ReadProperty();
1743 sealed class PropertyTable : Table<PropertyTable.Record>
1745 internal const int Index = 0x17;
1747 internal struct Record
1749 internal short Flags;
1754 internal override void Read(MetadataReader mr)
1756 for (int i = 0; i < records.Length; i++)
1758 records[i].Flags = mr.ReadInt16();
1759 records[i].Name = mr.ReadStringIndex();
1760 records[i].Type = mr.ReadBlobIndex();
1764 internal override void Write(MetadataWriter mw)
1766 for (int i = 0; i < rowCount; i++)
1768 mw.Write(records[i].Flags);
1769 mw.WriteStringIndex(records[i].Name);
1770 mw.WriteBlobIndex(records[i].Type);
1774 protected override int GetRowSize(RowSizeCalc rsc)
1784 sealed class MethodSemanticsTable : SortedTable<MethodSemanticsTable.Record>, IComparer<MethodSemanticsTable.Record>
1786 internal const int Index = 0x18;
1789 internal const short Setter = 0x0001;
1790 internal const short Getter = 0x0002;
1791 internal const short Other = 0x0004;
1792 internal const short AddOn = 0x0008;
1793 internal const short RemoveOn = 0x0010;
1794 internal const short Fire = 0x0020;
1796 internal struct Record : ISortKey
1798 internal short Semantics;
1799 internal int Method;
1800 internal int Association;
1804 get { return Association; }
1808 internal override void Read(MetadataReader mr)
1810 for (int i = 0; i < records.Length; i++)
1812 records[i].Semantics = mr.ReadInt16();
1813 records[i].Method = mr.ReadMethodDef();
1814 records[i].Association = mr.ReadHasSemantics();
1818 internal override void Write(MetadataWriter mw)
1820 for (int i = 0; i < rowCount; i++)
1822 mw.Write(records[i].Semantics);
1823 mw.WriteMethodDef(records[i].Method);
1824 mw.WriteHasSemantics(records[i].Association);
1828 protected override int GetRowSize(RowSizeCalc rsc)
1833 .WriteHasSemantics()
1837 internal void Fixup(ModuleBuilder moduleBuilder)
1839 for (int i = 0; i < rowCount; i++)
1841 if (moduleBuilder.IsPseudoToken(records[i].Method))
1843 records[i].Method = moduleBuilder.ResolvePseudoToken(records[i].Method);
1845 int token = records[i].Association;
1846 // do the HasSemantics encoding, so that we can sort the table
1847 switch (token >> 24)
1849 case EventTable.Index:
1850 token = (token & 0xFFFFFF) << 1 | 0;
1852 case PropertyTable.Index:
1853 token = (token & 0xFFFFFF) << 1 | 1;
1856 throw new InvalidOperationException();
1858 records[i].Association = token;
1863 int IComparer<Record>.Compare(Record x, Record y)
1865 return x.Association == y.Association ? 0 : (x.Association > y.Association ? 1 : -1);
1868 internal MethodInfo GetMethod(Module module, int token, bool nonPublic, short semantics)
1870 foreach (int i in Filter(token))
1872 if ((records[i].Semantics & semantics) != 0)
1874 MethodBase method = module.ResolveMethod((MethodDefTable.Index << 24) + records[i].Method);
1875 if (nonPublic || method.IsPublic)
1877 return (MethodInfo)method;
1884 internal MethodInfo[] GetMethods(Module module, int token, bool nonPublic, short semantics)
1886 List<MethodInfo> methods = new List<MethodInfo>();
1887 foreach (int i in Filter(token))
1889 if ((records[i].Semantics & semantics) != 0)
1891 MethodInfo method = (MethodInfo)module.ResolveMethod((MethodDefTable.Index << 24) + records[i].Method);
1892 if (nonPublic || method.IsPublic)
1894 methods.Add(method);
1898 return methods.ToArray();
1901 internal void ComputeFlags(Module module, int token, out bool isPublic, out bool isNonPrivate, out bool isStatic)
1904 isNonPrivate = false;
1906 foreach (int i in Filter(token))
1908 MethodBase method = module.ResolveMethod((MethodDefTable.Index << 24) + records[i].Method);
1909 isPublic |= method.IsPublic;
1910 isNonPrivate |= (method.Attributes & MethodAttributes.MemberAccessMask) > MethodAttributes.Private;
1911 isStatic |= method.IsStatic;
1916 sealed class MethodImplTable : SortedTable<MethodImplTable.Record>, IComparer<MethodImplTable.Record>
1918 internal const int Index = 0x19;
1920 internal struct Record : ISortKey
1923 internal int MethodBody;
1924 internal int MethodDeclaration;
1928 get { return Class; }
1932 internal override void Read(MetadataReader mr)
1934 for (int i = 0; i < records.Length; i++)
1936 records[i].Class = mr.ReadTypeDef();
1937 records[i].MethodBody = mr.ReadMethodDefOrRef();
1938 records[i].MethodDeclaration = mr.ReadMethodDefOrRef();
1942 internal override void Write(MetadataWriter mw)
1944 for (int i = 0; i < rowCount; i++)
1946 mw.WriteTypeDef(records[i].Class);
1947 mw.WriteMethodDefOrRef(records[i].MethodBody);
1948 mw.WriteMethodDefOrRef(records[i].MethodDeclaration);
1952 protected override int GetRowSize(RowSizeCalc rsc)
1956 .WriteMethodDefOrRef()
1957 .WriteMethodDefOrRef()
1961 internal void Fixup(ModuleBuilder moduleBuilder)
1963 for (int i = 0; i < rowCount; i++)
1965 if (moduleBuilder.IsPseudoToken(records[i].MethodBody))
1967 records[i].MethodBody = moduleBuilder.ResolvePseudoToken(records[i].MethodBody);
1969 if (moduleBuilder.IsPseudoToken(records[i].MethodDeclaration))
1971 records[i].MethodDeclaration = moduleBuilder.ResolvePseudoToken(records[i].MethodDeclaration);
1977 int IComparer<Record>.Compare(Record x, Record y)
1979 return x.Class == y.Class ? 0 : (x.Class > y.Class ? 1 : -1);
1983 sealed class ModuleRefTable : Table<int>
1985 internal const int Index = 0x1A;
1987 internal override void Read(MetadataReader mr)
1989 for (int i = 0; i < records.Length; i++)
1991 records[i] = mr.ReadStringIndex();
1995 internal override void Write(MetadataWriter mw)
1997 for (int i = 0; i < rowCount; i++)
1999 mw.WriteStringIndex(records[i]);
2003 protected override int GetRowSize(RowSizeCalc rsc)
2010 internal int FindOrAddRecord(int str)
2012 for (int i = 0; i < rowCount; i++)
2014 if (records[i] == str)
2019 return AddRecord(str);
2023 sealed class TypeSpecTable : Table<int>
2025 internal const int Index = 0x1B;
2027 internal override void Read(MetadataReader mr)
2029 for (int i = 0; i < records.Length; i++)
2031 records[i] = mr.ReadBlobIndex();
2035 internal override void Write(MetadataWriter mw)
2037 for (int i = 0; i < rowCount; i++)
2039 mw.WriteBlobIndex(records[i]);
2043 protected override int GetRowSize(Table.RowSizeCalc rsc)
2045 return rsc.WriteBlobIndex().Value;
2049 sealed class ImplMapTable : SortedTable<ImplMapTable.Record>, IComparer<ImplMapTable.Record>
2051 internal const int Index = 0x1C;
2053 internal struct Record : ISortKey
2055 internal short MappingFlags;
2056 internal int MemberForwarded;
2057 internal int ImportName;
2058 internal int ImportScope;
2062 get { return MemberForwarded; }
2066 internal override void Read(MetadataReader mr)
2068 for (int i = 0; i < records.Length; i++)
2070 records[i].MappingFlags = mr.ReadInt16();
2071 records[i].MemberForwarded = mr.ReadMemberForwarded();
2072 records[i].ImportName = mr.ReadStringIndex();
2073 records[i].ImportScope = mr.ReadModuleRef();
2077 internal override void Write(MetadataWriter mw)
2079 for (int i = 0; i < rowCount; i++)
2081 mw.Write(records[i].MappingFlags);
2082 mw.WriteMemberForwarded(records[i].MemberForwarded);
2083 mw.WriteStringIndex(records[i].ImportName);
2084 mw.WriteModuleRef(records[i].ImportScope);
2088 protected override int GetRowSize(RowSizeCalc rsc)
2092 .WriteMemberForwarded()
2098 internal void Fixup(ModuleBuilder moduleBuilder)
2100 for (int i = 0; i < rowCount; i++)
2102 if (moduleBuilder.IsPseudoToken(records[i].MemberForwarded))
2104 records[i].MemberForwarded = moduleBuilder.ResolvePseudoToken(records[i].MemberForwarded);
2107 Array.Sort(records, 0, rowCount, this);
2110 int IComparer<Record>.Compare(Record x, Record y)
2112 return x.MemberForwarded == y.MemberForwarded ? 0 : (x.MemberForwarded > y.MemberForwarded ? 1 : -1);
2116 sealed class FieldRVATable : SortedTable<FieldRVATable.Record>, IComparer<FieldRVATable.Record>
2118 internal const int Index = 0x1D;
2120 internal struct Record : ISortKey
2122 internal int RVA; // we set the high bit to signify that the RVA is in the CIL stream (instead of .sdata)
2127 get { return Field; }
2131 internal override void Read(MetadataReader mr)
2133 for (int i = 0; i < records.Length; i++)
2135 records[i].RVA = mr.ReadInt32();
2136 records[i].Field = mr.ReadField();
2140 internal override void Write(MetadataWriter mw)
2142 for (int i = 0; i < rowCount; i++)
2144 mw.Write(records[i].RVA);
2145 mw.WriteField(records[i].Field);
2149 protected override int GetRowSize(RowSizeCalc rsc)
2157 internal void Fixup(ModuleBuilder moduleBuilder, int sdataRVA, int cilRVA)
2159 for (int i = 0; i < rowCount; i++)
2161 if (records[i].RVA < 0)
2163 records[i].RVA = (records[i].RVA & 0x7fffffff) + cilRVA;
2167 records[i].RVA += sdataRVA;
2169 if (moduleBuilder.IsPseudoToken(records[i].Field))
2171 records[i].Field = moduleBuilder.ResolvePseudoToken(records[i].Field);
2174 Array.Sort(records, 0, rowCount, this);
2177 int IComparer<Record>.Compare(Record x, Record y)
2179 return x.Field == y.Field ? 0 : (x.Field > y.Field ? 1 : -1);
2183 sealed class AssemblyTable : Table<AssemblyTable.Record>
2185 internal const int Index = 0x20;
2187 internal struct Record
2189 internal int HashAlgId;
2190 internal ushort MajorVersion;
2191 internal ushort MinorVersion;
2192 internal ushort BuildNumber;
2193 internal ushort RevisionNumber;
2195 internal int PublicKey;
2197 internal int Culture;
2200 internal override void Read(MetadataReader mr)
2202 for (int i = 0; i < records.Length; i++)
2204 records[i].HashAlgId = mr.ReadInt32();
2205 records[i].MajorVersion = mr.ReadUInt16();
2206 records[i].MinorVersion = mr.ReadUInt16();
2207 records[i].BuildNumber = mr.ReadUInt16();
2208 records[i].RevisionNumber = mr.ReadUInt16();
2209 records[i].Flags = mr.ReadInt32();
2210 records[i].PublicKey = mr.ReadBlobIndex();
2211 records[i].Name = mr.ReadStringIndex();
2212 records[i].Culture = mr.ReadStringIndex();
2216 internal override void Write(MetadataWriter mw)
2218 for (int i = 0; i < rowCount; i++)
2220 mw.Write(records[i].HashAlgId);
2221 mw.Write(records[i].MajorVersion);
2222 mw.Write(records[i].MinorVersion);
2223 mw.Write(records[i].BuildNumber);
2224 mw.Write(records[i].RevisionNumber);
2225 mw.Write(records[i].Flags);
2226 mw.WriteBlobIndex(records[i].PublicKey);
2227 mw.WriteStringIndex(records[i].Name);
2228 mw.WriteStringIndex(records[i].Culture);
2232 protected override int GetRowSize(RowSizeCalc rsc)
2243 sealed class AssemblyRefTable : Table<AssemblyRefTable.Record>
2245 internal const int Index = 0x23;
2247 internal struct Record
2249 internal ushort MajorVersion;
2250 internal ushort MinorVersion;
2251 internal ushort BuildNumber;
2252 internal ushort RevisionNumber;
2254 internal int PublicKeyOrToken;
2256 internal int Culture;
2257 internal int HashValue;
2260 internal int FindOrAddRecord(Record rec)
2262 for (int i = 0; i < rowCount; i++)
2264 // note that we ignore HashValue here!
2265 if (records[i].Name == rec.Name
2266 && records[i].MajorVersion == rec.MajorVersion
2267 && records[i].MinorVersion == rec.MinorVersion
2268 && records[i].BuildNumber == rec.BuildNumber
2269 && records[i].RevisionNumber == rec.RevisionNumber
2270 && records[i].Flags == rec.Flags
2271 && records[i].PublicKeyOrToken == rec.PublicKeyOrToken
2272 && records[i].Culture == rec.Culture
2278 return AddRecord(rec);
2281 internal override void Read(MetadataReader mr)
2283 for (int i = 0; i < records.Length; i++)
2285 records[i].MajorVersion = mr.ReadUInt16();
2286 records[i].MinorVersion = mr.ReadUInt16();
2287 records[i].BuildNumber = mr.ReadUInt16();
2288 records[i].RevisionNumber = mr.ReadUInt16();
2289 records[i].Flags = mr.ReadInt32();
2290 records[i].PublicKeyOrToken = mr.ReadBlobIndex();
2291 records[i].Name = mr.ReadStringIndex();
2292 records[i].Culture = mr.ReadStringIndex();
2293 records[i].HashValue = mr.ReadBlobIndex();
2297 internal override void Write(MetadataWriter mw)
2299 for (int i = 0; i < rowCount; i++)
2301 mw.Write(records[i].MajorVersion);
2302 mw.Write(records[i].MinorVersion);
2303 mw.Write(records[i].BuildNumber);
2304 mw.Write(records[i].RevisionNumber);
2305 mw.Write(records[i].Flags);
2306 mw.WriteBlobIndex(records[i].PublicKeyOrToken);
2307 mw.WriteStringIndex(records[i].Name);
2308 mw.WriteStringIndex(records[i].Culture);
2309 mw.WriteBlobIndex(records[i].HashValue);
2313 protected override int GetRowSize(RowSizeCalc rsc)
2325 sealed class FileTable : Table<FileTable.Record>
2327 internal const int Index = 0x26;
2329 internal struct Record
2333 internal int HashValue;
2336 internal override void Read(MetadataReader mr)
2338 for (int i = 0; i < records.Length; i++)
2340 records[i].Flags = mr.ReadInt32();
2341 records[i].Name = mr.ReadStringIndex();
2342 records[i].HashValue = mr.ReadBlobIndex();
2346 internal override void Write(MetadataWriter mw)
2348 for (int i = 0; i < rowCount; i++)
2350 mw.Write(records[i].Flags);
2351 mw.WriteStringIndex(records[i].Name);
2352 mw.WriteBlobIndex(records[i].HashValue);
2356 protected override int GetRowSize(RowSizeCalc rsc)
2366 sealed class ExportedTypeTable : Table<ExportedTypeTable.Record>
2368 internal const int Index = 0x27;
2370 internal struct Record
2373 internal int TypeDefId;
2374 internal int TypeName;
2375 internal int TypeNamespace;
2376 internal int Implementation;
2379 internal override void Read(MetadataReader mr)
2381 for (int i = 0; i < records.Length; i++)
2383 records[i].Flags = mr.ReadInt32();
2384 records[i].TypeDefId = mr.ReadInt32();
2385 records[i].TypeName = mr.ReadStringIndex();
2386 records[i].TypeNamespace = mr.ReadStringIndex();
2387 records[i].Implementation = mr.ReadImplementation();
2391 internal override void Write(MetadataWriter mw)
2393 for (int i = 0; i < rowCount; i++)
2395 mw.Write(records[i].Flags);
2396 mw.Write(records[i].TypeDefId);
2397 mw.WriteStringIndex(records[i].TypeName);
2398 mw.WriteStringIndex(records[i].TypeNamespace);
2399 mw.WriteImplementation(records[i].Implementation);
2403 protected override int GetRowSize(RowSizeCalc rsc)
2409 .WriteImplementation()
2413 internal int FindOrAddRecord(Record rec)
2415 for (int i = 0; i < rowCount; i++)
2417 if (records[i].Implementation == rec.Implementation
2418 && records[i].TypeName == rec.TypeName
2419 && records[i].TypeNamespace == rec.TypeNamespace)
2424 return AddRecord(rec);
2428 sealed class ManifestResourceTable : Table<ManifestResourceTable.Record>
2430 internal const int Index = 0x28;
2432 internal struct Record
2434 internal int Offset;
2437 internal int Implementation;
2440 internal override void Read(MetadataReader mr)
2442 for (int i = 0; i < records.Length; i++)
2444 records[i].Offset = mr.ReadInt32();
2445 records[i].Flags = mr.ReadInt32();
2446 records[i].Name = mr.ReadStringIndex();
2447 records[i].Implementation = mr.ReadImplementation();
2451 internal override void Write(MetadataWriter mw)
2453 for (int i = 0; i < rowCount; i++)
2455 mw.Write(records[i].Offset);
2456 mw.Write(records[i].Flags);
2457 mw.WriteStringIndex(records[i].Name);
2458 mw.WriteImplementation(records[i].Implementation);
2462 protected override int GetRowSize(RowSizeCalc rsc)
2467 .WriteImplementation()
2472 sealed class NestedClassTable : SortedTable<NestedClassTable.Record>
2474 internal const int Index = 0x29;
2476 internal struct Record : ISortKey
2478 internal int NestedClass;
2479 internal int EnclosingClass;
2483 get { return NestedClass; }
2487 internal override void Read(MetadataReader mr)
2489 for (int i = 0; i < records.Length; i++)
2491 records[i].NestedClass = mr.ReadTypeDef();
2492 records[i].EnclosingClass = mr.ReadTypeDef();
2496 internal override void Write(MetadataWriter mw)
2498 for (int i = 0; i < rowCount; i++)
2500 mw.WriteTypeDef(records[i].NestedClass);
2501 mw.WriteTypeDef(records[i].EnclosingClass);
2505 protected override int GetRowSize(RowSizeCalc rsc)
2513 internal List<int> GetNestedClasses(int enclosingClass)
2515 List<int> nestedClasses = new List<int>();
2516 for (int i = 0; i < rowCount; i++)
2518 if (records[i].EnclosingClass == enclosingClass)
2520 nestedClasses.Add(records[i].NestedClass);
2523 return nestedClasses;
2527 sealed class GenericParamTable : SortedTable<GenericParamTable.Record>, IComparer<GenericParamTable.Record>
2529 internal const int Index = 0x2A;
2531 internal struct Record : ISortKey
2533 internal short Number;
2534 internal short Flags;
2537 // not part of the table, we use it to be able to fixup the GenericParamConstraint table
2538 internal int unsortedIndex;
2542 get { return Owner; }
2546 internal override void Read(MetadataReader mr)
2548 for (int i = 0; i < records.Length; i++)
2550 records[i].Number = mr.ReadInt16();
2551 records[i].Flags = mr.ReadInt16();
2552 records[i].Owner = mr.ReadTypeOrMethodDef();
2553 records[i].Name = mr.ReadStringIndex();
2557 internal override void Write(MetadataWriter mw)
2559 for (int i = 0; i < rowCount; i++)
2561 mw.Write(records[i].Number);
2562 mw.Write(records[i].Flags);
2563 mw.WriteTypeOrMethodDef(records[i].Owner);
2564 mw.WriteStringIndex(records[i].Name);
2568 protected override int GetRowSize(RowSizeCalc rsc)
2572 .WriteTypeOrMethodDef()
2577 internal void Fixup(ModuleBuilder moduleBuilder)
2579 for (int i = 0; i < rowCount; i++)
2581 int token = records[i].Owner;
2582 if (moduleBuilder.IsPseudoToken(token))
2584 token = moduleBuilder.ResolvePseudoToken(token);
2586 // do the TypeOrMethodDef encoding, so that we can sort the table
2587 switch (token >> 24)
2589 case TypeDefTable.Index:
2590 records[i].Owner = (token & 0xFFFFFF) << 1 | 0;
2592 case MethodDefTable.Index:
2593 records[i].Owner = (token & 0xFFFFFF) << 1 | 1;
2596 throw new InvalidOperationException();
2598 records[i].unsortedIndex = i;
2600 Array.Sort(records, 0, rowCount, this);
2603 int IComparer<Record>.Compare(Record x, Record y)
2605 if (x.Owner == y.Owner)
2607 return x.Number == y.Number ? 0 : (x.Number > y.Number ? 1 : -1);
2609 return x.Owner > y.Owner ? 1 : -1;
2612 internal void PatchAttribute(int token, GenericParameterAttributes genericParameterAttributes)
2614 records[(token & 0xFFFFFF) - 1].Flags = (short)genericParameterAttributes;
2617 internal int[] GetIndexFixup()
2619 int[] array = new int[rowCount];
2620 for (int i = 0; i < rowCount; i++)
2622 array[records[i].unsortedIndex] = i;
2627 internal int FindFirstByOwner(int token)
2629 foreach (int i in Filter(token))
2637 sealed class MethodSpecTable : Table<MethodSpecTable.Record>
2639 internal const int Index = 0x2B;
2641 internal struct Record
2643 internal int Method;
2644 internal int Instantiation;
2647 internal override void Read(MetadataReader mr)
2649 for (int i = 0; i < records.Length; i++)
2651 records[i].Method = mr.ReadMethodDefOrRef();
2652 records[i].Instantiation = mr.ReadBlobIndex();
2656 internal override void Write(MetadataWriter mw)
2658 for (int i = 0; i < rowCount; i++)
2660 mw.WriteMethodDefOrRef(records[i].Method);
2661 mw.WriteBlobIndex(records[i].Instantiation);
2665 protected override int GetRowSize(RowSizeCalc rsc)
2668 .WriteMethodDefOrRef()
2673 internal int FindOrAddRecord(Record record)
2675 for (int i = 0; i < rowCount; i++)
2677 if (records[i].Method == record.Method
2678 && records[i].Instantiation == record.Instantiation)
2683 return AddRecord(record);
2686 internal void Fixup(ModuleBuilder moduleBuilder)
2688 for (int i = 0; i < rowCount; i++)
2690 if (moduleBuilder.IsPseudoToken(records[i].Method))
2692 records[i].Method = moduleBuilder.ResolvePseudoToken(records[i].Method);
2698 sealed class GenericParamConstraintTable : SortedTable<GenericParamConstraintTable.Record>, IComparer<GenericParamConstraintTable.Record>
2700 internal const int Index = 0x2C;
2702 internal struct Record : ISortKey
2705 internal int Constraint;
2709 get { return Owner; }
2713 internal override void Read(MetadataReader mr)
2715 for (int i = 0; i < records.Length; i++)
2717 records[i].Owner = mr.ReadGenericParam();
2718 records[i].Constraint = mr.ReadTypeDefOrRef();
2722 internal override void Write(MetadataWriter mw)
2724 for (int i = 0; i < rowCount; i++)
2726 mw.WriteGenericParam(records[i].Owner);
2727 mw.WriteTypeDefOrRef(records[i].Constraint);
2731 protected override int GetRowSize(RowSizeCalc rsc)
2734 .WriteGenericParam()
2735 .WriteTypeDefOrRef()
2739 internal void Fixup(ModuleBuilder moduleBuilder)
2741 int[] fixups = moduleBuilder.GenericParam.GetIndexFixup();
2742 for (int i = 0; i < rowCount; i++)
2744 records[i].Owner = fixups[records[i].Owner - 1] + 1;
2749 int IComparer<Record>.Compare(Record x, Record y)
2751 return x.Owner == y.Owner ? 0 : (x.Owner > y.Owner ? 1 : -1);