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>
429 where T : SortedTable<T>.IRecord
431 internal interface IRecord
434 int FilterKey { get; }
437 internal struct Enumerable
439 private readonly SortedTable<T> table;
440 private readonly int token;
442 internal Enumerable(SortedTable<T> table, int token)
448 public Enumerator GetEnumerator()
450 T[] records = table.records;
453 return new Enumerator(records, table.RowCount - 1, -1, token);
455 int index = BinarySearch(records, table.RowCount, token & 0xFFFFFF);
458 return new Enumerator(null, 0, 1, -1);
461 while (start > 0 && (records[start - 1].FilterKey & 0xFFFFFF) == (token & 0xFFFFFF))
466 int max = table.RowCount - 1;
467 while (end < max && (records[end + 1].FilterKey & 0xFFFFFF) == (token & 0xFFFFFF))
471 return new Enumerator(records, end, start - 1, token);
474 private static int BinarySearch(T[] records, int length, int maskedToken)
477 int max = length - 1;
480 int mid = min + ((max - min) / 2);
481 int maskedValue = records[mid].FilterKey & 0xFFFFFF;
482 if (maskedToken == maskedValue)
486 else if (maskedToken < maskedValue)
499 internal struct Enumerator
501 private readonly T[] records;
502 private readonly int token;
503 private readonly int max;
506 internal Enumerator(T[] records, int max, int index, int token)
508 this.records = records;
516 get { return index; }
519 public bool MoveNext()
524 if (records[index].FilterKey == token)
533 internal Enumerable Filter(int token)
535 return new Enumerable(this, token);
538 protected void Sort()
540 ulong[] map = new ulong[rowCount];
541 for (uint i = 0; i < map.Length; i++)
543 map[i] = ((ulong)records[i].SortKey << 32) | i;
546 T[] newRecords = new T[rowCount];
547 for (int i = 0; i < map.Length; i++)
549 newRecords[i] = records[(int)map[i]];
551 records = newRecords;
555 sealed class ModuleTable : Table<ModuleTable.Record>
557 internal const int Index = 0x00;
559 internal struct Record
561 internal short Generation;
562 internal int Name; // -> StringHeap
563 internal int Mvid; // -> GuidHeap
564 internal int EncId; // -> GuidHeap
565 internal int EncBaseId; // -> GuidHeap
568 internal override void Read(MetadataReader mr)
570 for (int i = 0; i < records.Length; i++)
572 records[i].Generation = mr.ReadInt16();
573 records[i].Name = mr.ReadStringIndex();
574 records[i].Mvid = mr.ReadGuidIndex();
575 records[i].EncId = mr.ReadGuidIndex();
576 records[i].EncBaseId = mr.ReadGuidIndex();
580 internal override void Write(MetadataWriter mw)
582 for (int i = 0; i < rowCount; i++)
584 mw.Write(records[i].Generation);
585 mw.WriteStringIndex(records[i].Name);
586 mw.WriteGuidIndex(records[i].Mvid);
587 mw.WriteGuidIndex(records[i].EncId);
588 mw.WriteGuidIndex(records[i].EncBaseId);
592 protected override int GetRowSize(RowSizeCalc rsc)
603 internal void Add(short generation, int name, int mvid, int encid, int encbaseid)
605 Record record = new Record();
606 record.Generation = generation;
609 record.EncId = encid;
610 record.EncBaseId = encbaseid;
615 sealed class TypeRefTable : Table<TypeRefTable.Record>
617 internal const int Index = 0x01;
619 internal struct Record
621 internal int ResolutionScope;
622 internal int TypeName;
623 internal int TypeNameSpace;
626 internal override void Read(MetadataReader mr)
628 for (int i = 0; i < records.Length; i++)
630 records[i].ResolutionScope = mr.ReadResolutionScope();
631 records[i].TypeName = mr.ReadStringIndex();
632 records[i].TypeNameSpace = mr.ReadStringIndex();
636 internal override void Write(MetadataWriter mw)
638 for (int i = 0; i < rowCount; i++)
640 mw.WriteResolutionScope(records[i].ResolutionScope);
641 mw.WriteStringIndex(records[i].TypeName);
642 mw.WriteStringIndex(records[i].TypeNameSpace);
646 protected override int GetRowSize(RowSizeCalc rsc)
649 .WriteResolutionScope()
655 internal void Fixup(ModuleBuilder moduleBuilder)
657 for (int i = 0; i < rowCount; i++)
659 moduleBuilder.FixupPseudoToken(ref records[i].ResolutionScope);
664 sealed class TypeDefTable : Table<TypeDefTable.Record>
666 internal const int Index = 0x02;
668 internal struct Record
671 internal int TypeName;
672 internal int TypeNamespace;
673 internal int Extends;
674 internal int FieldList;
675 internal int MethodList;
678 internal override void Read(MetadataReader mr)
680 for (int i = 0; i < records.Length; i++)
682 records[i].Flags = mr.ReadInt32();
683 records[i].TypeName = mr.ReadStringIndex();
684 records[i].TypeNamespace = mr.ReadStringIndex();
685 records[i].Extends = mr.ReadTypeDefOrRef();
686 records[i].FieldList = mr.ReadField();
687 records[i].MethodList = mr.ReadMethodDef();
691 internal override void Write(MetadataWriter mw)
693 mw.ModuleBuilder.WriteTypeDefTable(mw);
696 internal int AllocToken()
698 return 0x02000000 + AddVirtualRecord();
701 protected override int GetRowSize(RowSizeCalc rsc)
714 sealed class FieldPtrTable : Table<int>
716 internal const int Index = 0x03;
718 internal override void Read(MetadataReader mr)
720 for (int i = 0; i < records.Length; i++)
722 records[i] = mr.ReadField();
727 sealed class FieldTable : Table<FieldTable.Record>
729 internal const int Index = 0x04;
731 internal struct Record
733 internal short Flags;
735 internal int Signature;
738 internal override void Read(MetadataReader mr)
740 for (int i = 0; i < records.Length; i++)
742 records[i].Flags = mr.ReadInt16();
743 records[i].Name = mr.ReadStringIndex();
744 records[i].Signature = mr.ReadBlobIndex();
748 internal override void Write(MetadataWriter mw)
750 mw.ModuleBuilder.WriteFieldTable(mw);
753 protected override int GetRowSize(RowSizeCalc rsc)
763 sealed class MethodPtrTable : Table<int>
765 internal const int Index = 0x05;
767 internal override void Read(MetadataReader mr)
769 for (int i = 0; i < records.Length; i++)
771 records[i] = mr.ReadMethodDef();
776 sealed class MethodDefTable : Table<MethodDefTable.Record>
778 internal const int Index = 0x06;
781 internal struct Record
784 internal short ImplFlags;
785 internal short Flags;
787 internal int Signature;
788 internal int ParamList;
791 internal override void Read(MetadataReader mr)
793 for (int i = 0; i < records.Length; i++)
795 records[i].RVA = mr.ReadInt32();
796 records[i].ImplFlags = mr.ReadInt16();
797 records[i].Flags = mr.ReadInt16();
798 records[i].Name = mr.ReadStringIndex();
799 records[i].Signature = mr.ReadBlobIndex();
800 records[i].ParamList = mr.ReadParam();
804 internal override void Write(MetadataWriter mw)
806 mw.ModuleBuilder.WriteMethodDefTable(baseRVA, mw);
809 protected override int GetRowSize(RowSizeCalc rsc)
819 internal void Fixup(TextSection code)
821 baseRVA = (int)code.MethodBodiesRVA;
825 sealed class ParamPtrTable : Table<int>
827 internal const int Index = 0x07;
829 internal override void Read(MetadataReader mr)
831 for (int i = 0; i < records.Length; i++)
833 records[i] = mr.ReadParam();
838 sealed class ParamTable : Table<ParamTable.Record>
840 internal const int Index = 0x08;
842 internal struct Record
844 internal short Flags;
845 internal short Sequence;
849 internal override void Read(MetadataReader mr)
851 for (int i = 0; i < records.Length; i++)
853 records[i].Flags = mr.ReadInt16();
854 records[i].Sequence = mr.ReadInt16();
855 records[i].Name = mr.ReadStringIndex();
859 internal override void Write(MetadataWriter mw)
861 mw.ModuleBuilder.WriteParamTable(mw);
864 protected override int GetRowSize(RowSizeCalc rsc)
873 sealed class InterfaceImplTable : SortedTable<InterfaceImplTable.Record>
875 internal const int Index = 0x09;
877 internal struct Record : IRecord
880 internal int Interface;
884 get { return Class; }
887 int IRecord.FilterKey
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 : IRecord
1018 internal short Type;
1019 internal int Parent;
1024 get { return EncodeHasConstant(Parent); }
1027 int IRecord.FilterKey
1029 get { return Parent; }
1033 internal override void Read(MetadataReader mr)
1035 for (int i = 0; i < records.Length; i++)
1037 records[i].Type = mr.ReadInt16();
1038 records[i].Parent = mr.ReadHasConstant();
1039 records[i].Value = mr.ReadBlobIndex();
1043 internal override void Write(MetadataWriter mw)
1045 for (int i = 0; i < rowCount; i++)
1047 mw.Write(records[i].Type);
1048 mw.WriteHasConstant(records[i].Parent);
1049 mw.WriteBlobIndex(records[i].Value);
1053 protected override int GetRowSize(RowSizeCalc rsc)
1062 internal void Fixup(ModuleBuilder moduleBuilder)
1064 for (int i = 0; i < rowCount; i++)
1066 moduleBuilder.FixupPseudoToken(ref records[i].Parent);
1071 internal static int EncodeHasConstant(int token)
1073 switch (token >> 24)
1075 case FieldTable.Index:
1076 return (token & 0xFFFFFF) << 2 | 0;
1077 case ParamTable.Index:
1078 return (token & 0xFFFFFF) << 2 | 1;
1079 case PropertyTable.Index:
1080 return (token & 0xFFFFFF) << 2 | 2;
1082 throw new InvalidOperationException();
1086 internal object GetRawConstantValue(Module module, int parent)
1088 foreach (int i in Filter(parent))
1090 ByteReader br = module.GetBlob(module.Constant.records[i].Value);
1091 switch (module.Constant.records[i].Type)
1093 // see ModuleBuilder.AddConstant for the encodings
1094 case Signature.ELEMENT_TYPE_BOOLEAN:
1095 return br.ReadByte() != 0;
1096 case Signature.ELEMENT_TYPE_I1:
1097 return br.ReadSByte();
1098 case Signature.ELEMENT_TYPE_I2:
1099 return br.ReadInt16();
1100 case Signature.ELEMENT_TYPE_I4:
1101 return br.ReadInt32();
1102 case Signature.ELEMENT_TYPE_I8:
1103 return br.ReadInt64();
1104 case Signature.ELEMENT_TYPE_U1:
1105 return br.ReadByte();
1106 case Signature.ELEMENT_TYPE_U2:
1107 return br.ReadUInt16();
1108 case Signature.ELEMENT_TYPE_U4:
1109 return br.ReadUInt32();
1110 case Signature.ELEMENT_TYPE_U8:
1111 return br.ReadUInt64();
1112 case Signature.ELEMENT_TYPE_R4:
1113 return br.ReadSingle();
1114 case Signature.ELEMENT_TYPE_R8:
1115 return br.ReadDouble();
1116 case Signature.ELEMENT_TYPE_CHAR:
1117 return br.ReadChar();
1118 case Signature.ELEMENT_TYPE_STRING:
1120 char[] chars = new char[br.Length / 2];
1121 for (int j = 0; j < chars.Length; j++)
1123 chars[j] = br.ReadChar();
1125 return new String(chars);
1127 case Signature.ELEMENT_TYPE_CLASS:
1128 if (br.ReadInt32() != 0)
1130 throw new BadImageFormatException();
1134 throw new BadImageFormatException();
1137 throw new InvalidOperationException();
1141 sealed class CustomAttributeTable : SortedTable<CustomAttributeTable.Record>
1143 internal const int Index = 0x0C;
1145 internal struct Record : IRecord
1147 internal int Parent;
1153 get { return EncodeHasCustomAttribute(Parent); }
1156 int IRecord.FilterKey
1158 get { return Parent; }
1162 internal override void Read(MetadataReader mr)
1164 for (int i = 0; i < records.Length; i++)
1166 records[i].Parent = mr.ReadHasCustomAttribute();
1167 records[i].Type = mr.ReadCustomAttributeType();
1168 records[i].Value = mr.ReadBlobIndex();
1172 internal override void Write(MetadataWriter mw)
1174 for (int i = 0; i < rowCount; i++)
1176 mw.WriteHasCustomAttribute(records[i].Parent);
1177 mw.WriteCustomAttributeType(records[i].Type);
1178 mw.WriteBlobIndex(records[i].Value);
1182 protected override int GetRowSize(RowSizeCalc rsc)
1185 .WriteHasCustomAttribute()
1186 .WriteCustomAttributeType()
1191 internal void Fixup(ModuleBuilder moduleBuilder)
1193 int[] genericParamFixup = moduleBuilder.GenericParam.GetIndexFixup();
1194 for (int i = 0; i < rowCount; i++)
1196 moduleBuilder.FixupPseudoToken(ref records[i].Type);
1197 moduleBuilder.FixupPseudoToken(ref records[i].Parent);
1198 if (records[i].Parent >> 24 == GenericParamTable.Index)
1200 records[i].Parent = (GenericParamTable.Index << 24) + genericParamFixup[(records[i].Parent & 0xFFFFFF) - 1] + 1;
1206 internal static int EncodeHasCustomAttribute(int token)
1208 switch (token >> 24)
1210 case MethodDefTable.Index:
1211 return (token & 0xFFFFFF) << 5 | 0;
1212 case FieldTable.Index:
1213 return (token & 0xFFFFFF) << 5 | 1;
1214 case TypeRefTable.Index:
1215 return (token & 0xFFFFFF) << 5 | 2;
1216 case TypeDefTable.Index:
1217 return (token & 0xFFFFFF) << 5 | 3;
1218 case ParamTable.Index:
1219 return (token & 0xFFFFFF) << 5 | 4;
1220 case InterfaceImplTable.Index:
1221 return (token & 0xFFFFFF) << 5 | 5;
1222 case MemberRefTable.Index:
1223 return (token & 0xFFFFFF) << 5 | 6;
1224 case ModuleTable.Index:
1225 return (token & 0xFFFFFF) << 5 | 7;
1226 // Permission (8) table doesn't exist in the spec
1227 case PropertyTable.Index:
1228 return (token & 0xFFFFFF) << 5 | 9;
1229 case EventTable.Index:
1230 return (token & 0xFFFFFF) << 5 | 10;
1231 case StandAloneSigTable.Index:
1232 return (token & 0xFFFFFF) << 5 | 11;
1233 case ModuleRefTable.Index:
1234 return (token & 0xFFFFFF) << 5 | 12;
1235 case TypeSpecTable.Index:
1236 return (token & 0xFFFFFF) << 5 | 13;
1237 case AssemblyTable.Index:
1238 return (token & 0xFFFFFF) << 5 | 14;
1239 case AssemblyRefTable.Index:
1240 return (token & 0xFFFFFF) << 5 | 15;
1241 case FileTable.Index:
1242 return (token & 0xFFFFFF) << 5 | 16;
1243 case ExportedTypeTable.Index:
1244 return (token & 0xFFFFFF) << 5 | 17;
1245 case ManifestResourceTable.Index:
1246 return (token & 0xFFFFFF) << 5 | 18;
1247 case GenericParamTable.Index:
1248 return (token & 0xFFFFFF) << 5 | 19;
1250 throw new InvalidOperationException();
1255 sealed class FieldMarshalTable : SortedTable<FieldMarshalTable.Record>
1257 internal const int Index = 0x0D;
1259 internal struct Record : IRecord
1261 internal int Parent;
1262 internal int NativeType;
1266 get { return EncodeHasFieldMarshal(Parent); }
1269 int IRecord.FilterKey
1271 get { return Parent; }
1275 internal override void Read(MetadataReader mr)
1277 for (int i = 0; i < records.Length; i++)
1279 records[i].Parent = mr.ReadHasFieldMarshal();
1280 records[i].NativeType = mr.ReadBlobIndex();
1284 internal override void Write(MetadataWriter mw)
1286 for (int i = 0; i < rowCount; i++)
1288 mw.WriteHasFieldMarshal(records[i].Parent);
1289 mw.WriteBlobIndex(records[i].NativeType);
1293 protected override int GetRowSize(RowSizeCalc rsc)
1296 .WriteHasFieldMarshal()
1301 internal void Fixup(ModuleBuilder moduleBuilder)
1303 for (int i = 0; i < rowCount; i++)
1305 records[i].Parent = moduleBuilder.ResolvePseudoToken(records[i].Parent);
1310 internal static int EncodeHasFieldMarshal(int token)
1312 switch (token >> 24)
1314 case FieldTable.Index:
1315 return (token & 0xFFFFFF) << 1 | 0;
1316 case ParamTable.Index:
1317 return (token & 0xFFFFFF) << 1 | 1;
1319 throw new InvalidOperationException();
1324 sealed class DeclSecurityTable : SortedTable<DeclSecurityTable.Record>
1326 internal const int Index = 0x0E;
1328 internal struct Record : IRecord
1330 internal short Action;
1331 internal int Parent;
1332 internal int PermissionSet;
1336 get { return Parent; }
1339 int IRecord.FilterKey
1341 get { return Parent; }
1345 internal override void Read(MetadataReader mr)
1347 for (int i = 0; i < records.Length; i++)
1349 records[i].Action = mr.ReadInt16();
1350 records[i].Parent = mr.ReadHasDeclSecurity();
1351 records[i].PermissionSet = mr.ReadBlobIndex();
1355 internal override void Write(MetadataWriter mw)
1357 for (int i = 0; i < rowCount; i++)
1359 mw.Write(records[i].Action);
1360 mw.WriteHasDeclSecurity(records[i].Parent);
1361 mw.WriteBlobIndex(records[i].PermissionSet);
1365 protected override int GetRowSize(RowSizeCalc rsc)
1369 .WriteHasDeclSecurity()
1374 internal void Fixup(ModuleBuilder moduleBuilder)
1376 for (int i = 0; i < rowCount; i++)
1378 int token = records[i].Parent;
1379 moduleBuilder.FixupPseudoToken(ref token);
1380 // do the HasDeclSecurity encoding, so that we can sort the table
1381 switch (token >> 24)
1383 case TypeDefTable.Index:
1384 token = (token & 0xFFFFFF) << 2 | 0;
1386 case MethodDefTable.Index:
1387 token = (token & 0xFFFFFF) << 2 | 1;
1389 case AssemblyTable.Index:
1390 token = (token & 0xFFFFFF) << 2 | 2;
1393 throw new InvalidOperationException();
1395 records[i].Parent = token;
1401 sealed class ClassLayoutTable : SortedTable<ClassLayoutTable.Record>
1403 internal const int Index = 0x0f;
1405 internal struct Record : IRecord
1407 internal short PackingSize;
1408 internal int ClassSize;
1409 internal int Parent;
1413 get { return Parent; }
1416 int IRecord.FilterKey
1418 get { return Parent; }
1422 internal override void Read(MetadataReader mr)
1424 for (int i = 0; i < records.Length; i++)
1426 records[i].PackingSize = mr.ReadInt16();
1427 records[i].ClassSize = mr.ReadInt32();
1428 records[i].Parent = mr.ReadTypeDef();
1432 internal override void Write(MetadataWriter mw)
1435 for (int i = 0; i < rowCount; i++)
1437 mw.Write(records[i].PackingSize);
1438 mw.Write(records[i].ClassSize);
1439 mw.WriteTypeDef(records[i].Parent);
1443 protected override int GetRowSize(RowSizeCalc rsc)
1452 sealed class FieldLayoutTable : SortedTable<FieldLayoutTable.Record>
1454 internal const int Index = 0x10;
1456 internal struct Record : IRecord
1458 internal int Offset;
1463 get { return Field; }
1466 int IRecord.FilterKey
1468 get { return Field; }
1472 internal override void Read(MetadataReader mr)
1474 for (int i = 0; i < records.Length; i++)
1476 records[i].Offset = mr.ReadInt32();
1477 records[i].Field = mr.ReadField();
1481 internal override void Write(MetadataWriter mw)
1483 for (int i = 0; i < rowCount; i++)
1485 mw.Write(records[i].Offset);
1486 mw.WriteField(records[i].Field);
1490 protected override int GetRowSize(RowSizeCalc rsc)
1498 internal void Fixup(ModuleBuilder moduleBuilder)
1500 for (int i = 0; i < rowCount; i++)
1502 records[i].Field = moduleBuilder.ResolvePseudoToken(records[i].Field) & 0xFFFFFF;
1508 sealed class StandAloneSigTable : Table<int>
1510 internal const int Index = 0x11;
1512 internal override void Read(MetadataReader mr)
1514 for (int i = 0; i < records.Length; i++)
1516 records[i] = mr.ReadBlobIndex();
1520 internal override void Write(MetadataWriter mw)
1522 for (int i = 0; i < rowCount; i++)
1524 mw.WriteBlobIndex(records[i]);
1528 protected override int GetRowSize(Table.RowSizeCalc rsc)
1530 return rsc.WriteBlobIndex().Value;
1533 internal int FindOrAddRecord(int blob)
1535 for (int i = 0; i < rowCount; i++)
1537 if (records[i] == blob)
1542 return AddRecord(blob);
1546 sealed class EventMapTable : SortedTable<EventMapTable.Record>
1548 internal const int Index = 0x12;
1550 internal struct Record : IRecord
1552 internal int Parent;
1553 internal int EventList;
1557 get { return Parent; }
1560 int IRecord.FilterKey
1562 get { return Parent; }
1566 internal override void Read(MetadataReader mr)
1568 for (int i = 0; i < records.Length; i++)
1570 records[i].Parent = mr.ReadTypeDef();
1571 records[i].EventList = mr.ReadEvent();
1575 internal override void Write(MetadataWriter mw)
1577 for (int i = 0; i < rowCount; i++)
1579 mw.WriteTypeDef(records[i].Parent);
1580 mw.WriteEvent(records[i].EventList);
1584 protected override int GetRowSize(RowSizeCalc rsc)
1593 sealed class EventPtrTable : Table<int>
1595 internal const int Index = 0x13;
1597 internal override void Read(MetadataReader mr)
1599 for (int i = 0; i < records.Length; i++)
1601 records[i] = mr.ReadEvent();
1606 sealed class EventTable : Table<EventTable.Record>
1608 internal const int Index = 0x14;
1610 internal struct Record
1612 internal short EventFlags;
1614 internal int EventType;
1617 internal override void Read(MetadataReader mr)
1619 for (int i = 0; i < records.Length; i++)
1621 records[i].EventFlags = mr.ReadInt16();
1622 records[i].Name = mr.ReadStringIndex();
1623 records[i].EventType = mr.ReadTypeDefOrRef();
1627 internal override void Write(MetadataWriter mw)
1629 for (int i = 0; i < rowCount; i++)
1631 mw.Write(records[i].EventFlags);
1632 mw.WriteStringIndex(records[i].Name);
1633 mw.WriteTypeDefOrRef(records[i].EventType);
1637 protected override int GetRowSize(RowSizeCalc rsc)
1642 .WriteTypeDefOrRef()
1647 sealed class PropertyMapTable : SortedTable<PropertyMapTable.Record>
1649 internal const int Index = 0x15;
1651 internal struct Record : IRecord
1653 internal int Parent;
1654 internal int PropertyList;
1658 get { return Parent; }
1661 int IRecord.FilterKey
1663 get { return Parent; }
1667 internal override void Read(MetadataReader mr)
1669 for (int i = 0; i < records.Length; i++)
1671 records[i].Parent = mr.ReadTypeDef();
1672 records[i].PropertyList = mr.ReadProperty();
1676 internal override void Write(MetadataWriter mw)
1678 for (int i = 0; i < rowCount; i++)
1680 mw.WriteTypeDef(records[i].Parent);
1681 mw.WriteProperty(records[i].PropertyList);
1685 protected override int GetRowSize(RowSizeCalc rsc)
1694 sealed class PropertyPtrTable : Table<int>
1696 internal const int Index = 0x16;
1698 internal override void Read(MetadataReader mr)
1700 for (int i = 0; i < records.Length; i++)
1702 records[i] = mr.ReadProperty();
1707 sealed class PropertyTable : Table<PropertyTable.Record>
1709 internal const int Index = 0x17;
1711 internal struct Record
1713 internal short Flags;
1718 internal override void Read(MetadataReader mr)
1720 for (int i = 0; i < records.Length; i++)
1722 records[i].Flags = mr.ReadInt16();
1723 records[i].Name = mr.ReadStringIndex();
1724 records[i].Type = mr.ReadBlobIndex();
1728 internal override void Write(MetadataWriter mw)
1730 for (int i = 0; i < rowCount; i++)
1732 mw.Write(records[i].Flags);
1733 mw.WriteStringIndex(records[i].Name);
1734 mw.WriteBlobIndex(records[i].Type);
1738 protected override int GetRowSize(RowSizeCalc rsc)
1748 sealed class MethodSemanticsTable : SortedTable<MethodSemanticsTable.Record>
1750 internal const int Index = 0x18;
1753 internal const short Setter = 0x0001;
1754 internal const short Getter = 0x0002;
1755 internal const short Other = 0x0004;
1756 internal const short AddOn = 0x0008;
1757 internal const short RemoveOn = 0x0010;
1758 internal const short Fire = 0x0020;
1760 internal struct Record : IRecord
1762 internal short Semantics;
1763 internal int Method;
1764 internal int Association;
1768 get { return Association; }
1771 int IRecord.FilterKey
1773 get { return Association; }
1777 internal override void Read(MetadataReader mr)
1779 for (int i = 0; i < records.Length; i++)
1781 records[i].Semantics = mr.ReadInt16();
1782 records[i].Method = mr.ReadMethodDef();
1783 records[i].Association = mr.ReadHasSemantics();
1787 internal override void Write(MetadataWriter mw)
1789 for (int i = 0; i < rowCount; i++)
1791 mw.Write(records[i].Semantics);
1792 mw.WriteMethodDef(records[i].Method);
1793 mw.WriteHasSemantics(records[i].Association);
1797 protected override int GetRowSize(RowSizeCalc rsc)
1802 .WriteHasSemantics()
1806 internal void Fixup(ModuleBuilder moduleBuilder)
1808 for (int i = 0; i < rowCount; i++)
1810 moduleBuilder.FixupPseudoToken(ref records[i].Method);
1811 int token = records[i].Association;
1812 // do the HasSemantics encoding, so that we can sort the table
1813 switch (token >> 24)
1815 case EventTable.Index:
1816 token = (token & 0xFFFFFF) << 1 | 0;
1818 case PropertyTable.Index:
1819 token = (token & 0xFFFFFF) << 1 | 1;
1822 throw new InvalidOperationException();
1824 records[i].Association = token;
1829 internal MethodInfo GetMethod(Module module, int token, bool nonPublic, short semantics)
1831 foreach (int i in Filter(token))
1833 if ((records[i].Semantics & semantics) != 0)
1835 MethodBase method = module.ResolveMethod((MethodDefTable.Index << 24) + records[i].Method);
1836 if (nonPublic || method.IsPublic)
1838 return (MethodInfo)method;
1845 internal MethodInfo[] GetMethods(Module module, int token, bool nonPublic, short semantics)
1847 List<MethodInfo> methods = new List<MethodInfo>();
1848 foreach (int i in Filter(token))
1850 if ((records[i].Semantics & semantics) != 0)
1852 MethodInfo method = (MethodInfo)module.ResolveMethod((MethodDefTable.Index << 24) + records[i].Method);
1853 if (nonPublic || method.IsPublic)
1855 methods.Add(method);
1859 return methods.ToArray();
1862 internal void ComputeFlags(Module module, int token, out bool isPublic, out bool isNonPrivate, out bool isStatic)
1865 isNonPrivate = false;
1867 foreach (int i in Filter(token))
1869 MethodBase method = module.ResolveMethod((MethodDefTable.Index << 24) + records[i].Method);
1870 isPublic |= method.IsPublic;
1871 isNonPrivate |= (method.Attributes & MethodAttributes.MemberAccessMask) > MethodAttributes.Private;
1872 isStatic |= method.IsStatic;
1877 sealed class MethodImplTable : SortedTable<MethodImplTable.Record>
1879 internal const int Index = 0x19;
1881 internal struct Record : IRecord
1884 internal int MethodBody;
1885 internal int MethodDeclaration;
1889 get { return Class; }
1892 int IRecord.FilterKey
1894 get { return Class; }
1898 internal override void Read(MetadataReader mr)
1900 for (int i = 0; i < records.Length; i++)
1902 records[i].Class = mr.ReadTypeDef();
1903 records[i].MethodBody = mr.ReadMethodDefOrRef();
1904 records[i].MethodDeclaration = mr.ReadMethodDefOrRef();
1908 internal override void Write(MetadataWriter mw)
1910 for (int i = 0; i < rowCount; i++)
1912 mw.WriteTypeDef(records[i].Class);
1913 mw.WriteMethodDefOrRef(records[i].MethodBody);
1914 mw.WriteMethodDefOrRef(records[i].MethodDeclaration);
1918 protected override int GetRowSize(RowSizeCalc rsc)
1922 .WriteMethodDefOrRef()
1923 .WriteMethodDefOrRef()
1927 internal void Fixup(ModuleBuilder moduleBuilder)
1929 for (int i = 0; i < rowCount; i++)
1931 moduleBuilder.FixupPseudoToken(ref records[i].MethodBody);
1932 moduleBuilder.FixupPseudoToken(ref records[i].MethodDeclaration);
1938 sealed class ModuleRefTable : Table<int>
1940 internal const int Index = 0x1A;
1942 internal override void Read(MetadataReader mr)
1944 for (int i = 0; i < records.Length; i++)
1946 records[i] = mr.ReadStringIndex();
1950 internal override void Write(MetadataWriter mw)
1952 for (int i = 0; i < rowCount; i++)
1954 mw.WriteStringIndex(records[i]);
1958 protected override int GetRowSize(RowSizeCalc rsc)
1965 internal int FindOrAddRecord(int str)
1967 for (int i = 0; i < rowCount; i++)
1969 if (records[i] == str)
1974 return AddRecord(str);
1978 sealed class TypeSpecTable : Table<int>
1980 internal const int Index = 0x1B;
1982 internal override void Read(MetadataReader mr)
1984 for (int i = 0; i < records.Length; i++)
1986 records[i] = mr.ReadBlobIndex();
1990 internal override void Write(MetadataWriter mw)
1992 for (int i = 0; i < rowCount; i++)
1994 mw.WriteBlobIndex(records[i]);
1998 protected override int GetRowSize(Table.RowSizeCalc rsc)
2000 return rsc.WriteBlobIndex().Value;
2004 sealed class ImplMapTable : SortedTable<ImplMapTable.Record>
2006 internal const int Index = 0x1C;
2008 internal struct Record : IRecord
2010 internal short MappingFlags;
2011 internal int MemberForwarded;
2012 internal int ImportName;
2013 internal int ImportScope;
2017 get { return MemberForwarded; }
2020 int IRecord.FilterKey
2022 get { return MemberForwarded; }
2026 internal override void Read(MetadataReader mr)
2028 for (int i = 0; i < records.Length; i++)
2030 records[i].MappingFlags = mr.ReadInt16();
2031 records[i].MemberForwarded = mr.ReadMemberForwarded();
2032 records[i].ImportName = mr.ReadStringIndex();
2033 records[i].ImportScope = mr.ReadModuleRef();
2037 internal override void Write(MetadataWriter mw)
2039 for (int i = 0; i < rowCount; i++)
2041 mw.Write(records[i].MappingFlags);
2042 mw.WriteMemberForwarded(records[i].MemberForwarded);
2043 mw.WriteStringIndex(records[i].ImportName);
2044 mw.WriteModuleRef(records[i].ImportScope);
2048 protected override int GetRowSize(RowSizeCalc rsc)
2052 .WriteMemberForwarded()
2058 internal void Fixup(ModuleBuilder moduleBuilder)
2060 for (int i = 0; i < rowCount; i++)
2062 moduleBuilder.FixupPseudoToken(ref records[i].MemberForwarded);
2068 sealed class FieldRVATable : SortedTable<FieldRVATable.Record>
2070 internal const int Index = 0x1D;
2072 internal struct Record : IRecord
2074 internal int RVA; // we set the high bit to signify that the RVA is in the CIL stream (instead of .sdata)
2079 get { return Field; }
2082 int IRecord.FilterKey
2084 get { return Field; }
2088 internal override void Read(MetadataReader mr)
2090 for (int i = 0; i < records.Length; i++)
2092 records[i].RVA = mr.ReadInt32();
2093 records[i].Field = mr.ReadField();
2097 internal override void Write(MetadataWriter mw)
2099 for (int i = 0; i < rowCount; i++)
2101 mw.Write(records[i].RVA);
2102 mw.WriteField(records[i].Field);
2106 protected override int GetRowSize(RowSizeCalc rsc)
2114 internal void Fixup(ModuleBuilder moduleBuilder, int sdataRVA, int cilRVA)
2116 for (int i = 0; i < rowCount; i++)
2118 if (records[i].RVA < 0)
2120 records[i].RVA = (records[i].RVA & 0x7fffffff) + cilRVA;
2124 records[i].RVA += sdataRVA;
2126 moduleBuilder.FixupPseudoToken(ref records[i].Field);
2132 sealed class AssemblyTable : Table<AssemblyTable.Record>
2134 internal const int Index = 0x20;
2136 internal struct Record
2138 internal int HashAlgId;
2139 internal ushort MajorVersion;
2140 internal ushort MinorVersion;
2141 internal ushort BuildNumber;
2142 internal ushort RevisionNumber;
2144 internal int PublicKey;
2146 internal int Culture;
2149 internal override void Read(MetadataReader mr)
2151 for (int i = 0; i < records.Length; i++)
2153 records[i].HashAlgId = mr.ReadInt32();
2154 records[i].MajorVersion = mr.ReadUInt16();
2155 records[i].MinorVersion = mr.ReadUInt16();
2156 records[i].BuildNumber = mr.ReadUInt16();
2157 records[i].RevisionNumber = mr.ReadUInt16();
2158 records[i].Flags = mr.ReadInt32();
2159 records[i].PublicKey = mr.ReadBlobIndex();
2160 records[i].Name = mr.ReadStringIndex();
2161 records[i].Culture = mr.ReadStringIndex();
2165 internal override void Write(MetadataWriter mw)
2167 for (int i = 0; i < rowCount; i++)
2169 mw.Write(records[i].HashAlgId);
2170 mw.Write(records[i].MajorVersion);
2171 mw.Write(records[i].MinorVersion);
2172 mw.Write(records[i].BuildNumber);
2173 mw.Write(records[i].RevisionNumber);
2174 mw.Write(records[i].Flags);
2175 mw.WriteBlobIndex(records[i].PublicKey);
2176 mw.WriteStringIndex(records[i].Name);
2177 mw.WriteStringIndex(records[i].Culture);
2181 protected override int GetRowSize(RowSizeCalc rsc)
2192 sealed class AssemblyRefTable : Table<AssemblyRefTable.Record>
2194 internal const int Index = 0x23;
2196 internal struct Record
2198 internal ushort MajorVersion;
2199 internal ushort MinorVersion;
2200 internal ushort BuildNumber;
2201 internal ushort RevisionNumber;
2203 internal int PublicKeyOrToken;
2205 internal int Culture;
2206 internal int HashValue;
2209 internal int FindOrAddRecord(Record rec)
2211 for (int i = 0; i < rowCount; i++)
2213 // note that we ignore HashValue here!
2214 if (records[i].Name == rec.Name
2215 && records[i].MajorVersion == rec.MajorVersion
2216 && records[i].MinorVersion == rec.MinorVersion
2217 && records[i].BuildNumber == rec.BuildNumber
2218 && records[i].RevisionNumber == rec.RevisionNumber
2219 && records[i].Flags == rec.Flags
2220 && records[i].PublicKeyOrToken == rec.PublicKeyOrToken
2221 && records[i].Culture == rec.Culture
2227 return AddRecord(rec);
2230 internal override void Read(MetadataReader mr)
2232 for (int i = 0; i < records.Length; i++)
2234 records[i].MajorVersion = mr.ReadUInt16();
2235 records[i].MinorVersion = mr.ReadUInt16();
2236 records[i].BuildNumber = mr.ReadUInt16();
2237 records[i].RevisionNumber = mr.ReadUInt16();
2238 records[i].Flags = mr.ReadInt32();
2239 records[i].PublicKeyOrToken = mr.ReadBlobIndex();
2240 records[i].Name = mr.ReadStringIndex();
2241 records[i].Culture = mr.ReadStringIndex();
2242 records[i].HashValue = mr.ReadBlobIndex();
2246 internal override void Write(MetadataWriter mw)
2248 for (int i = 0; i < rowCount; i++)
2250 mw.Write(records[i].MajorVersion);
2251 mw.Write(records[i].MinorVersion);
2252 mw.Write(records[i].BuildNumber);
2253 mw.Write(records[i].RevisionNumber);
2254 mw.Write(records[i].Flags);
2255 mw.WriteBlobIndex(records[i].PublicKeyOrToken);
2256 mw.WriteStringIndex(records[i].Name);
2257 mw.WriteStringIndex(records[i].Culture);
2258 mw.WriteBlobIndex(records[i].HashValue);
2262 protected override int GetRowSize(RowSizeCalc rsc)
2274 sealed class FileTable : Table<FileTable.Record>
2276 internal const int Index = 0x26;
2278 internal struct Record
2282 internal int HashValue;
2285 internal override void Read(MetadataReader mr)
2287 for (int i = 0; i < records.Length; i++)
2289 records[i].Flags = mr.ReadInt32();
2290 records[i].Name = mr.ReadStringIndex();
2291 records[i].HashValue = mr.ReadBlobIndex();
2295 internal override void Write(MetadataWriter mw)
2297 for (int i = 0; i < rowCount; i++)
2299 mw.Write(records[i].Flags);
2300 mw.WriteStringIndex(records[i].Name);
2301 mw.WriteBlobIndex(records[i].HashValue);
2305 protected override int GetRowSize(RowSizeCalc rsc)
2315 sealed class ExportedTypeTable : Table<ExportedTypeTable.Record>
2317 internal const int Index = 0x27;
2319 internal struct Record
2322 internal int TypeDefId;
2323 internal int TypeName;
2324 internal int TypeNamespace;
2325 internal int Implementation;
2328 internal override void Read(MetadataReader mr)
2330 for (int i = 0; i < records.Length; i++)
2332 records[i].Flags = mr.ReadInt32();
2333 records[i].TypeDefId = mr.ReadInt32();
2334 records[i].TypeName = mr.ReadStringIndex();
2335 records[i].TypeNamespace = mr.ReadStringIndex();
2336 records[i].Implementation = mr.ReadImplementation();
2340 internal override void Write(MetadataWriter mw)
2342 for (int i = 0; i < rowCount; i++)
2344 mw.Write(records[i].Flags);
2345 mw.Write(records[i].TypeDefId);
2346 mw.WriteStringIndex(records[i].TypeName);
2347 mw.WriteStringIndex(records[i].TypeNamespace);
2348 mw.WriteImplementation(records[i].Implementation);
2352 protected override int GetRowSize(RowSizeCalc rsc)
2358 .WriteImplementation()
2362 internal int FindOrAddRecord(Record rec)
2364 for (int i = 0; i < rowCount; i++)
2366 if (records[i].Implementation == rec.Implementation
2367 && records[i].TypeName == rec.TypeName
2368 && records[i].TypeNamespace == rec.TypeNamespace)
2373 return AddRecord(rec);
2376 internal void Fixup(ModuleBuilder moduleBuilder)
2378 for (int i = 0; i < rowCount; i++)
2380 moduleBuilder.FixupPseudoToken(ref records[i].Implementation);
2385 sealed class ManifestResourceTable : Table<ManifestResourceTable.Record>
2387 internal const int Index = 0x28;
2389 internal struct Record
2391 internal int Offset;
2394 internal int Implementation;
2397 internal override void Read(MetadataReader mr)
2399 for (int i = 0; i < records.Length; i++)
2401 records[i].Offset = mr.ReadInt32();
2402 records[i].Flags = mr.ReadInt32();
2403 records[i].Name = mr.ReadStringIndex();
2404 records[i].Implementation = mr.ReadImplementation();
2408 internal override void Write(MetadataWriter mw)
2410 for (int i = 0; i < rowCount; i++)
2412 mw.Write(records[i].Offset);
2413 mw.Write(records[i].Flags);
2414 mw.WriteStringIndex(records[i].Name);
2415 mw.WriteImplementation(records[i].Implementation);
2419 protected override int GetRowSize(RowSizeCalc rsc)
2424 .WriteImplementation()
2428 internal void Fixup(ModuleBuilder moduleBuilder)
2430 for (int i = 0; i < rowCount; i++)
2432 moduleBuilder.FixupPseudoToken(ref records[i].Implementation);
2437 sealed class NestedClassTable : SortedTable<NestedClassTable.Record>
2439 internal const int Index = 0x29;
2441 internal struct Record : IRecord
2443 internal int NestedClass;
2444 internal int EnclosingClass;
2448 get { return NestedClass; }
2451 int IRecord.FilterKey
2453 get { return NestedClass; }
2457 internal override void Read(MetadataReader mr)
2459 for (int i = 0; i < records.Length; i++)
2461 records[i].NestedClass = mr.ReadTypeDef();
2462 records[i].EnclosingClass = mr.ReadTypeDef();
2466 internal override void Write(MetadataWriter mw)
2468 for (int i = 0; i < rowCount; i++)
2470 mw.WriteTypeDef(records[i].NestedClass);
2471 mw.WriteTypeDef(records[i].EnclosingClass);
2475 protected override int GetRowSize(RowSizeCalc rsc)
2483 internal List<int> GetNestedClasses(int enclosingClass)
2485 List<int> nestedClasses = new List<int>();
2486 for (int i = 0; i < rowCount; i++)
2488 if (records[i].EnclosingClass == enclosingClass)
2490 nestedClasses.Add(records[i].NestedClass);
2493 return nestedClasses;
2497 sealed class GenericParamTable : SortedTable<GenericParamTable.Record>, IComparer<GenericParamTable.Record>
2499 internal const int Index = 0x2A;
2501 internal struct Record : IRecord
2503 internal short Number;
2504 internal short Flags;
2507 // not part of the table, we use it to be able to fixup the GenericParamConstraint table
2508 internal int unsortedIndex;
2512 get { return Owner; }
2515 int IRecord.FilterKey
2517 get { return Owner; }
2521 internal override void Read(MetadataReader mr)
2523 for (int i = 0; i < records.Length; i++)
2525 records[i].Number = mr.ReadInt16();
2526 records[i].Flags = mr.ReadInt16();
2527 records[i].Owner = mr.ReadTypeOrMethodDef();
2528 records[i].Name = mr.ReadStringIndex();
2532 internal override void Write(MetadataWriter mw)
2534 for (int i = 0; i < rowCount; i++)
2536 mw.Write(records[i].Number);
2537 mw.Write(records[i].Flags);
2538 mw.WriteTypeOrMethodDef(records[i].Owner);
2539 mw.WriteStringIndex(records[i].Name);
2543 protected override int GetRowSize(RowSizeCalc rsc)
2547 .WriteTypeOrMethodDef()
2552 internal void Fixup(ModuleBuilder moduleBuilder)
2554 for (int i = 0; i < rowCount; i++)
2556 int token = records[i].Owner;
2557 moduleBuilder.FixupPseudoToken(ref token);
2558 // do the TypeOrMethodDef encoding, so that we can sort the table
2559 switch (token >> 24)
2561 case TypeDefTable.Index:
2562 records[i].Owner = (token & 0xFFFFFF) << 1 | 0;
2564 case MethodDefTable.Index:
2565 records[i].Owner = (token & 0xFFFFFF) << 1 | 1;
2568 throw new InvalidOperationException();
2570 records[i].unsortedIndex = i;
2572 // FXBUG the unnecessary (IComparer<Record>) cast is a workaround for a .NET 2.0 C# compiler bug
2573 Array.Sort(records, 0, rowCount, (IComparer<Record>)this);
2576 int IComparer<Record>.Compare(Record x, Record y)
2578 if (x.Owner == y.Owner)
2580 return x.Number == y.Number ? 0 : (x.Number > y.Number ? 1 : -1);
2582 return x.Owner > y.Owner ? 1 : -1;
2585 internal void PatchAttribute(int token, GenericParameterAttributes genericParameterAttributes)
2587 records[(token & 0xFFFFFF) - 1].Flags = (short)genericParameterAttributes;
2590 internal int[] GetIndexFixup()
2592 int[] array = new int[rowCount];
2593 for (int i = 0; i < rowCount; i++)
2595 array[records[i].unsortedIndex] = i;
2600 internal int FindFirstByOwner(int token)
2602 foreach (int i in Filter(token))
2610 sealed class MethodSpecTable : Table<MethodSpecTable.Record>
2612 internal const int Index = 0x2B;
2614 internal struct Record
2616 internal int Method;
2617 internal int Instantiation;
2620 internal override void Read(MetadataReader mr)
2622 for (int i = 0; i < records.Length; i++)
2624 records[i].Method = mr.ReadMethodDefOrRef();
2625 records[i].Instantiation = mr.ReadBlobIndex();
2629 internal override void Write(MetadataWriter mw)
2631 for (int i = 0; i < rowCount; i++)
2633 mw.WriteMethodDefOrRef(records[i].Method);
2634 mw.WriteBlobIndex(records[i].Instantiation);
2638 protected override int GetRowSize(RowSizeCalc rsc)
2641 .WriteMethodDefOrRef()
2646 internal int FindOrAddRecord(Record record)
2648 for (int i = 0; i < rowCount; i++)
2650 if (records[i].Method == record.Method
2651 && records[i].Instantiation == record.Instantiation)
2656 return AddRecord(record);
2659 internal void Fixup(ModuleBuilder moduleBuilder)
2661 for (int i = 0; i < rowCount; i++)
2663 moduleBuilder.FixupPseudoToken(ref records[i].Method);
2668 sealed class GenericParamConstraintTable : SortedTable<GenericParamConstraintTable.Record>
2670 internal const int Index = 0x2C;
2672 internal struct Record : IRecord
2675 internal int Constraint;
2679 get { return Owner; }
2682 int IRecord.FilterKey
2684 get { return Owner; }
2688 internal override void Read(MetadataReader mr)
2690 for (int i = 0; i < records.Length; i++)
2692 records[i].Owner = mr.ReadGenericParam();
2693 records[i].Constraint = mr.ReadTypeDefOrRef();
2697 internal override void Write(MetadataWriter mw)
2699 for (int i = 0; i < rowCount; i++)
2701 mw.WriteGenericParam(records[i].Owner);
2702 mw.WriteTypeDefOrRef(records[i].Constraint);
2706 protected override int GetRowSize(RowSizeCalc rsc)
2709 .WriteGenericParam()
2710 .WriteTypeDefOrRef()
2714 internal void Fixup(ModuleBuilder moduleBuilder)
2716 int[] fixups = moduleBuilder.GenericParam.GetIndexFixup();
2717 for (int i = 0; i < rowCount; i++)
2719 records[i].Owner = fixups[records[i].Owner - 1] + 1;