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 = Empty<T>.Array;
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
Array.Resize(ref records, Math.Max(16, records.Length * 2));
411
records[rowCount++] = newRecord;
415
internal int AddVirtualRecord()
420
internal override void Write(MetadataWriter mw)
422
throw new InvalidOperationException();
426
abstract class SortedTable<T> : Table<T>
427
where T : SortedTable<T>.IRecord
429
internal interface IRecord
432
int FilterKey { get; }
435
internal struct Enumerable
437
private readonly SortedTable<T> table;
438
private readonly int token;
440
internal Enumerable(SortedTable<T> table, int token)
446
public Enumerator GetEnumerator()
448
T[] records = table.records;
451
return new Enumerator(records, table.RowCount - 1, -1, token);
453
int index = BinarySearch(records, table.RowCount, token & 0xFFFFFF);
456
return new Enumerator(null, 0, 1, -1);
459
while (start > 0 && (records[start - 1].FilterKey & 0xFFFFFF) == (token & 0xFFFFFF))
464
int max = table.RowCount - 1;
465
while (end < max && (records[end + 1].FilterKey & 0xFFFFFF) == (token & 0xFFFFFF))
469
return new Enumerator(records, end, start - 1, token);
472
private static int BinarySearch(T[] records, int length, int maskedToken)
475
int max = length - 1;
478
int mid = min + ((max - min) / 2);
479
int maskedValue = records[mid].FilterKey & 0xFFFFFF;
480
if (maskedToken == maskedValue)
484
else if (maskedToken < maskedValue)
497
internal struct Enumerator
499
private readonly T[] records;
500
private readonly int token;
501
private readonly int max;
504
internal Enumerator(T[] records, int max, int index, int token)
506
this.records = records;
514
get { return index; }
517
public bool MoveNext()
522
if (records[index].FilterKey == token)
531
internal Enumerable Filter(int token)
533
return new Enumerable(this, token);
536
protected void Sort()
538
ulong[] map = new ulong[rowCount];
539
for (uint i = 0; i < map.Length; i++)
541
map[i] = ((ulong)records[i].SortKey << 32) | i;
544
T[] newRecords = new T[rowCount];
545
for (int i = 0; i < map.Length; i++)
547
newRecords[i] = records[(int)map[i]];
549
records = newRecords;
553
sealed class ModuleTable : Table<ModuleTable.Record>
555
internal const int Index = 0x00;
557
internal struct Record
559
internal short Generation;
560
internal int Name; // -> StringHeap
561
internal int Mvid; // -> GuidHeap
562
internal int EncId; // -> GuidHeap
563
internal int EncBaseId; // -> GuidHeap
566
internal override void Read(MetadataReader mr)
568
for (int i = 0; i < records.Length; i++)
570
records[i].Generation = mr.ReadInt16();
571
records[i].Name = mr.ReadStringIndex();
572
records[i].Mvid = mr.ReadGuidIndex();
573
records[i].EncId = mr.ReadGuidIndex();
574
records[i].EncBaseId = mr.ReadGuidIndex();
578
internal override void Write(MetadataWriter mw)
580
for (int i = 0; i < rowCount; i++)
582
mw.Write(records[i].Generation);
583
mw.WriteStringIndex(records[i].Name);
584
mw.WriteGuidIndex(records[i].Mvid);
585
mw.WriteGuidIndex(records[i].EncId);
586
mw.WriteGuidIndex(records[i].EncBaseId);
590
protected override int GetRowSize(RowSizeCalc rsc)
601
internal void Add(short generation, int name, int mvid, int encid, int encbaseid)
603
Record record = new Record();
604
record.Generation = generation;
607
record.EncId = encid;
608
record.EncBaseId = encbaseid;
613
sealed class TypeRefTable : Table<TypeRefTable.Record>
615
internal const int Index = 0x01;
617
internal struct Record
619
internal int ResolutionScope;
620
internal int TypeName;
621
internal int TypeNameSpace;
624
internal override void Read(MetadataReader mr)
626
for (int i = 0; i < records.Length; i++)
628
records[i].ResolutionScope = mr.ReadResolutionScope();
629
records[i].TypeName = mr.ReadStringIndex();
630
records[i].TypeNameSpace = mr.ReadStringIndex();
634
internal override void Write(MetadataWriter mw)
636
for (int i = 0; i < rowCount; i++)
638
mw.WriteResolutionScope(records[i].ResolutionScope);
639
mw.WriteStringIndex(records[i].TypeName);
640
mw.WriteStringIndex(records[i].TypeNameSpace);
644
protected override int GetRowSize(RowSizeCalc rsc)
647
.WriteResolutionScope()
653
internal void Fixup(ModuleBuilder moduleBuilder)
655
for (int i = 0; i < rowCount; i++)
657
moduleBuilder.FixupPseudoToken(ref records[i].ResolutionScope);
662
sealed class TypeDefTable : Table<TypeDefTable.Record>
664
internal const int Index = 0x02;
666
internal struct Record
669
internal int TypeName;
670
internal int TypeNamespace;
671
internal int Extends;
672
internal int FieldList;
673
internal int MethodList;
676
internal override void Read(MetadataReader mr)
678
for (int i = 0; i < records.Length; i++)
680
records[i].Flags = mr.ReadInt32();
681
records[i].TypeName = mr.ReadStringIndex();
682
records[i].TypeNamespace = mr.ReadStringIndex();
683
records[i].Extends = mr.ReadTypeDefOrRef();
684
records[i].FieldList = mr.ReadField();
685
records[i].MethodList = mr.ReadMethodDef();
689
internal override void Write(MetadataWriter mw)
691
mw.ModuleBuilder.WriteTypeDefTable(mw);
694
internal int AllocToken()
696
return 0x02000000 + AddVirtualRecord();
699
protected override int GetRowSize(RowSizeCalc rsc)
712
sealed class FieldPtrTable : Table<int>
714
internal const int Index = 0x03;
716
internal override void Read(MetadataReader mr)
718
for (int i = 0; i < records.Length; i++)
720
records[i] = mr.ReadField();
725
sealed class FieldTable : Table<FieldTable.Record>
727
internal const int Index = 0x04;
729
internal struct Record
731
internal short Flags;
733
internal int Signature;
736
internal override void Read(MetadataReader mr)
738
for (int i = 0; i < records.Length; i++)
740
records[i].Flags = mr.ReadInt16();
741
records[i].Name = mr.ReadStringIndex();
742
records[i].Signature = mr.ReadBlobIndex();
746
internal override void Write(MetadataWriter mw)
748
mw.ModuleBuilder.WriteFieldTable(mw);
751
protected override int GetRowSize(RowSizeCalc rsc)
761
sealed class MethodPtrTable : Table<int>
763
internal const int Index = 0x05;
765
internal override void Read(MetadataReader mr)
767
for (int i = 0; i < records.Length; i++)
769
records[i] = mr.ReadMethodDef();
774
sealed class MethodDefTable : Table<MethodDefTable.Record>
776
internal const int Index = 0x06;
779
internal struct Record
782
internal short ImplFlags;
783
internal short Flags;
785
internal int Signature;
786
internal int ParamList;
789
internal override void Read(MetadataReader mr)
791
for (int i = 0; i < records.Length; i++)
793
records[i].RVA = mr.ReadInt32();
794
records[i].ImplFlags = mr.ReadInt16();
795
records[i].Flags = mr.ReadInt16();
796
records[i].Name = mr.ReadStringIndex();
797
records[i].Signature = mr.ReadBlobIndex();
798
records[i].ParamList = mr.ReadParam();
802
internal override void Write(MetadataWriter mw)
804
mw.ModuleBuilder.WriteMethodDefTable(baseRVA, mw);
807
protected override int GetRowSize(RowSizeCalc rsc)
817
internal void Fixup(TextSection code)
819
baseRVA = (int)code.MethodBodiesRVA;
823
sealed class ParamPtrTable : Table<int>
825
internal const int Index = 0x07;
827
internal override void Read(MetadataReader mr)
829
for (int i = 0; i < records.Length; i++)
831
records[i] = mr.ReadParam();
836
sealed class ParamTable : Table<ParamTable.Record>
838
internal const int Index = 0x08;
840
internal struct Record
842
internal short Flags;
843
internal short Sequence;
847
internal override void Read(MetadataReader mr)
849
for (int i = 0; i < records.Length; i++)
851
records[i].Flags = mr.ReadInt16();
852
records[i].Sequence = mr.ReadInt16();
853
records[i].Name = mr.ReadStringIndex();
857
internal override void Write(MetadataWriter mw)
859
mw.ModuleBuilder.WriteParamTable(mw);
862
protected override int GetRowSize(RowSizeCalc rsc)
871
sealed class InterfaceImplTable : SortedTable<InterfaceImplTable.Record>
873
internal const int Index = 0x09;
875
internal struct Record : IRecord
878
internal int Interface;
882
get { return Class; }
885
int IRecord.FilterKey
887
get { return Class; }
891
internal override void Read(MetadataReader mr)
893
for (int i = 0; i < records.Length; i++)
895
records[i].Class = mr.ReadTypeDef();
896
records[i].Interface = mr.ReadTypeDefOrRef();
900
internal override void Write(MetadataWriter mw)
902
for (int i = 0; i < rowCount; i++)
904
mw.WriteTypeDef(records[i].Class);
905
mw.WriteEncodedTypeDefOrRef(records[i].Interface);
909
protected override int GetRowSize(RowSizeCalc rsc)
917
internal void Fixup()
919
for (int i = 0; i < rowCount; i++)
921
int token = records[i].Interface;
926
case TypeDefTable.Index:
927
token = (token & 0xFFFFFF) << 2 | 0;
929
case TypeRefTable.Index:
930
token = (token & 0xFFFFFF) << 2 | 1;
932
case TypeSpecTable.Index:
933
token = (token & 0xFFFFFF) << 2 | 2;
936
throw new InvalidOperationException();
938
records[i].Interface = token;
940
// LAMESPEC the CLI spec says that InterfaceImpl should be sorted by { Class, Interface },
941
// but it appears to only be necessary to sort by Class (and csc emits InterfaceImpl records in
942
// source file order, so to be able to support round tripping, we need to retain ordering as well).
947
sealed class MemberRefTable : Table<MemberRefTable.Record>
949
internal const int Index = 0x0A;
951
internal struct Record
955
internal int Signature;
958
internal override void Read(MetadataReader mr)
960
for (int i = 0; i < records.Length; i++)
962
records[i].Class = mr.ReadMemberRefParent();
963
records[i].Name = mr.ReadStringIndex();
964
records[i].Signature = mr.ReadBlobIndex();
968
internal override void Write(MetadataWriter mw)
970
for (int i = 0; i < rowCount; i++)
972
mw.WriteMemberRefParent(records[i].Class);
973
mw.WriteStringIndex(records[i].Name);
974
mw.WriteBlobIndex(records[i].Signature);
978
protected override int GetRowSize(RowSizeCalc rsc)
981
.WriteMemberRefParent()
987
internal int FindOrAddRecord(Record record)
989
for (int i = 0; i < rowCount; i++)
991
if (records[i].Class == record.Class
992
&& records[i].Name == record.Name
993
&& records[i].Signature == record.Signature)
998
return AddRecord(record);
1001
internal void Fixup(ModuleBuilder moduleBuilder)
1003
for (int i = 0; i < rowCount; i++)
1005
moduleBuilder.FixupPseudoToken(ref records[i].Class);
1010
sealed class ConstantTable : SortedTable<ConstantTable.Record>
1012
internal const int Index = 0x0B;
1014
internal struct Record : IRecord
1016
internal short Type;
1017
internal int Parent;
1022
get { return EncodeHasConstant(Parent); }
1025
int IRecord.FilterKey
1027
get { return Parent; }
1031
internal override void Read(MetadataReader mr)
1033
for (int i = 0; i < records.Length; i++)
1035
records[i].Type = mr.ReadInt16();
1036
records[i].Parent = mr.ReadHasConstant();
1037
records[i].Value = mr.ReadBlobIndex();
1041
internal override void Write(MetadataWriter mw)
1043
for (int i = 0; i < rowCount; i++)
1045
mw.Write(records[i].Type);
1046
mw.WriteHasConstant(records[i].Parent);
1047
mw.WriteBlobIndex(records[i].Value);
1051
protected override int GetRowSize(RowSizeCalc rsc)
1060
internal void Fixup(ModuleBuilder moduleBuilder)
1062
for (int i = 0; i < rowCount; i++)
1064
moduleBuilder.FixupPseudoToken(ref records[i].Parent);
1069
internal static int EncodeHasConstant(int token)
1071
switch (token >> 24)
1073
case FieldTable.Index:
1074
return (token & 0xFFFFFF) << 2 | 0;
1075
case ParamTable.Index:
1076
return (token & 0xFFFFFF) << 2 | 1;
1077
case PropertyTable.Index:
1078
return (token & 0xFFFFFF) << 2 | 2;
1080
throw new InvalidOperationException();
1084
internal object GetRawConstantValue(Module module, int parent)
1086
foreach (int i in Filter(parent))
1088
ByteReader br = module.GetBlob(module.Constant.records[i].Value);
1089
switch (module.Constant.records[i].Type)
1091
// see ModuleBuilder.AddConstant for the encodings
1092
case Signature.ELEMENT_TYPE_BOOLEAN:
1093
return br.ReadByte() != 0;
1094
case Signature.ELEMENT_TYPE_I1:
1095
return br.ReadSByte();
1096
case Signature.ELEMENT_TYPE_I2:
1097
return br.ReadInt16();
1098
case Signature.ELEMENT_TYPE_I4:
1099
return br.ReadInt32();
1100
case Signature.ELEMENT_TYPE_I8:
1101
return br.ReadInt64();
1102
case Signature.ELEMENT_TYPE_U1:
1103
return br.ReadByte();
1104
case Signature.ELEMENT_TYPE_U2:
1105
return br.ReadUInt16();
1106
case Signature.ELEMENT_TYPE_U4:
1107
return br.ReadUInt32();
1108
case Signature.ELEMENT_TYPE_U8:
1109
return br.ReadUInt64();
1110
case Signature.ELEMENT_TYPE_R4:
1111
return br.ReadSingle();
1112
case Signature.ELEMENT_TYPE_R8:
1113
return br.ReadDouble();
1114
case Signature.ELEMENT_TYPE_CHAR:
1115
return br.ReadChar();
1116
case Signature.ELEMENT_TYPE_STRING:
1118
char[] chars = new char[br.Length / 2];
1119
for (int j = 0; j < chars.Length; j++)
1121
chars[j] = br.ReadChar();
1123
return new String(chars);
1125
case Signature.ELEMENT_TYPE_CLASS:
1126
if (br.ReadInt32() != 0)
1128
throw new BadImageFormatException();
1132
throw new BadImageFormatException();
1135
throw new InvalidOperationException();
1139
sealed class CustomAttributeTable : SortedTable<CustomAttributeTable.Record>
1141
internal const int Index = 0x0C;
1143
internal struct Record : IRecord
1145
internal int Parent;
1151
get { return EncodeHasCustomAttribute(Parent); }
1154
int IRecord.FilterKey
1156
get { return Parent; }
1160
internal override void Read(MetadataReader mr)
1162
for (int i = 0; i < records.Length; i++)
1164
records[i].Parent = mr.ReadHasCustomAttribute();
1165
records[i].Type = mr.ReadCustomAttributeType();
1166
records[i].Value = mr.ReadBlobIndex();
1170
internal override void Write(MetadataWriter mw)
1172
for (int i = 0; i < rowCount; i++)
1174
mw.WriteHasCustomAttribute(records[i].Parent);
1175
mw.WriteCustomAttributeType(records[i].Type);
1176
mw.WriteBlobIndex(records[i].Value);
1180
protected override int GetRowSize(RowSizeCalc rsc)
1183
.WriteHasCustomAttribute()
1184
.WriteCustomAttributeType()
1189
internal void Fixup(ModuleBuilder moduleBuilder)
1191
int[] genericParamFixup = moduleBuilder.GenericParam.GetIndexFixup();
1192
for (int i = 0; i < rowCount; i++)
1194
moduleBuilder.FixupPseudoToken(ref records[i].Type);
1195
moduleBuilder.FixupPseudoToken(ref records[i].Parent);
1196
if (records[i].Parent >> 24 == GenericParamTable.Index)
1198
records[i].Parent = (GenericParamTable.Index << 24) + genericParamFixup[(records[i].Parent & 0xFFFFFF) - 1] + 1;
1204
internal static int EncodeHasCustomAttribute(int token)
1206
switch (token >> 24)
1208
case MethodDefTable.Index:
1209
return (token & 0xFFFFFF) << 5 | 0;
1210
case FieldTable.Index:
1211
return (token & 0xFFFFFF) << 5 | 1;
1212
case TypeRefTable.Index:
1213
return (token & 0xFFFFFF) << 5 | 2;
1214
case TypeDefTable.Index:
1215
return (token & 0xFFFFFF) << 5 | 3;
1216
case ParamTable.Index:
1217
return (token & 0xFFFFFF) << 5 | 4;
1218
case InterfaceImplTable.Index:
1219
return (token & 0xFFFFFF) << 5 | 5;
1220
case MemberRefTable.Index:
1221
return (token & 0xFFFFFF) << 5 | 6;
1222
case ModuleTable.Index:
1223
return (token & 0xFFFFFF) << 5 | 7;
1224
// Permission (8) table doesn't exist in the spec
1225
case PropertyTable.Index:
1226
return (token & 0xFFFFFF) << 5 | 9;
1227
case EventTable.Index:
1228
return (token & 0xFFFFFF) << 5 | 10;
1229
case StandAloneSigTable.Index:
1230
return (token & 0xFFFFFF) << 5 | 11;
1231
case ModuleRefTable.Index:
1232
return (token & 0xFFFFFF) << 5 | 12;
1233
case TypeSpecTable.Index:
1234
return (token & 0xFFFFFF) << 5 | 13;
1235
case AssemblyTable.Index:
1236
return (token & 0xFFFFFF) << 5 | 14;
1237
case AssemblyRefTable.Index:
1238
return (token & 0xFFFFFF) << 5 | 15;
1239
case FileTable.Index:
1240
return (token & 0xFFFFFF) << 5 | 16;
1241
case ExportedTypeTable.Index:
1242
return (token & 0xFFFFFF) << 5 | 17;
1243
case ManifestResourceTable.Index:
1244
return (token & 0xFFFFFF) << 5 | 18;
1245
case GenericParamTable.Index:
1246
return (token & 0xFFFFFF) << 5 | 19;
1248
throw new InvalidOperationException();
1253
sealed class FieldMarshalTable : SortedTable<FieldMarshalTable.Record>
1255
internal const int Index = 0x0D;
1257
internal struct Record : IRecord
1259
internal int Parent;
1260
internal int NativeType;
1264
get { return EncodeHasFieldMarshal(Parent); }
1267
int IRecord.FilterKey
1269
get { return Parent; }
1273
internal override void Read(MetadataReader mr)
1275
for (int i = 0; i < records.Length; i++)
1277
records[i].Parent = mr.ReadHasFieldMarshal();
1278
records[i].NativeType = mr.ReadBlobIndex();
1282
internal override void Write(MetadataWriter mw)
1284
for (int i = 0; i < rowCount; i++)
1286
mw.WriteHasFieldMarshal(records[i].Parent);
1287
mw.WriteBlobIndex(records[i].NativeType);
1291
protected override int GetRowSize(RowSizeCalc rsc)
1294
.WriteHasFieldMarshal()
1299
internal void Fixup(ModuleBuilder moduleBuilder)
1301
for (int i = 0; i < rowCount; i++)
1303
records[i].Parent = moduleBuilder.ResolvePseudoToken(records[i].Parent);
1308
internal static int EncodeHasFieldMarshal(int token)
1310
switch (token >> 24)
1312
case FieldTable.Index:
1313
return (token & 0xFFFFFF) << 1 | 0;
1314
case ParamTable.Index:
1315
return (token & 0xFFFFFF) << 1 | 1;
1317
throw new InvalidOperationException();
1322
sealed class DeclSecurityTable : SortedTable<DeclSecurityTable.Record>
1324
internal const int Index = 0x0E;
1326
internal struct Record : IRecord
1328
internal short Action;
1329
internal int Parent;
1330
internal int PermissionSet;
1334
get { return Parent; }
1337
int IRecord.FilterKey
1339
get { return Parent; }
1343
internal override void Read(MetadataReader mr)
1345
for (int i = 0; i < records.Length; i++)
1347
records[i].Action = mr.ReadInt16();
1348
records[i].Parent = mr.ReadHasDeclSecurity();
1349
records[i].PermissionSet = mr.ReadBlobIndex();
1353
internal override void Write(MetadataWriter mw)
1355
for (int i = 0; i < rowCount; i++)
1357
mw.Write(records[i].Action);
1358
mw.WriteHasDeclSecurity(records[i].Parent);
1359
mw.WriteBlobIndex(records[i].PermissionSet);
1363
protected override int GetRowSize(RowSizeCalc rsc)
1367
.WriteHasDeclSecurity()
1372
internal void Fixup(ModuleBuilder moduleBuilder)
1374
for (int i = 0; i < rowCount; i++)
1376
int token = records[i].Parent;
1377
moduleBuilder.FixupPseudoToken(ref token);
1378
// do the HasDeclSecurity encoding, so that we can sort the table
1379
switch (token >> 24)
1381
case TypeDefTable.Index:
1382
token = (token & 0xFFFFFF) << 2 | 0;
1384
case MethodDefTable.Index:
1385
token = (token & 0xFFFFFF) << 2 | 1;
1387
case AssemblyTable.Index:
1388
token = (token & 0xFFFFFF) << 2 | 2;
1391
throw new InvalidOperationException();
1393
records[i].Parent = token;
1399
sealed class ClassLayoutTable : SortedTable<ClassLayoutTable.Record>
1401
internal const int Index = 0x0f;
1403
internal struct Record : IRecord
1405
internal short PackingSize;
1406
internal int ClassSize;
1407
internal int Parent;
1411
get { return Parent; }
1414
int IRecord.FilterKey
1416
get { return Parent; }
1420
internal override void Read(MetadataReader mr)
1422
for (int i = 0; i < records.Length; i++)
1424
records[i].PackingSize = mr.ReadInt16();
1425
records[i].ClassSize = mr.ReadInt32();
1426
records[i].Parent = mr.ReadTypeDef();
1430
internal override void Write(MetadataWriter mw)
1433
for (int i = 0; i < rowCount; i++)
1435
mw.Write(records[i].PackingSize);
1436
mw.Write(records[i].ClassSize);
1437
mw.WriteTypeDef(records[i].Parent);
1441
protected override int GetRowSize(RowSizeCalc rsc)
1450
sealed class FieldLayoutTable : SortedTable<FieldLayoutTable.Record>
1452
internal const int Index = 0x10;
1454
internal struct Record : IRecord
1456
internal int Offset;
1461
get { return Field; }
1464
int IRecord.FilterKey
1466
get { return Field; }
1470
internal override void Read(MetadataReader mr)
1472
for (int i = 0; i < records.Length; i++)
1474
records[i].Offset = mr.ReadInt32();
1475
records[i].Field = mr.ReadField();
1479
internal override void Write(MetadataWriter mw)
1481
for (int i = 0; i < rowCount; i++)
1483
mw.Write(records[i].Offset);
1484
mw.WriteField(records[i].Field);
1488
protected override int GetRowSize(RowSizeCalc rsc)
1496
internal void Fixup(ModuleBuilder moduleBuilder)
1498
for (int i = 0; i < rowCount; i++)
1500
records[i].Field = moduleBuilder.ResolvePseudoToken(records[i].Field) & 0xFFFFFF;
1506
sealed class StandAloneSigTable : Table<int>
1508
internal const int Index = 0x11;
1510
internal override void Read(MetadataReader mr)
1512
for (int i = 0; i < records.Length; i++)
1514
records[i] = mr.ReadBlobIndex();
1518
internal override void Write(MetadataWriter mw)
1520
for (int i = 0; i < rowCount; i++)
1522
mw.WriteBlobIndex(records[i]);
1526
protected override int GetRowSize(Table.RowSizeCalc rsc)
1528
return rsc.WriteBlobIndex().Value;
1531
internal int FindOrAddRecord(int blob)
1533
for (int i = 0; i < rowCount; i++)
1535
if (records[i] == blob)
1540
return AddRecord(blob);
1544
sealed class EventMapTable : SortedTable<EventMapTable.Record>
1546
internal const int Index = 0x12;
1548
internal struct Record : IRecord
1550
internal int Parent;
1551
internal int EventList;
1555
get { return Parent; }
1558
int IRecord.FilterKey
1560
get { return Parent; }
1564
internal override void Read(MetadataReader mr)
1566
for (int i = 0; i < records.Length; i++)
1568
records[i].Parent = mr.ReadTypeDef();
1569
records[i].EventList = mr.ReadEvent();
1573
internal override void Write(MetadataWriter mw)
1575
for (int i = 0; i < rowCount; i++)
1577
mw.WriteTypeDef(records[i].Parent);
1578
mw.WriteEvent(records[i].EventList);
1582
protected override int GetRowSize(RowSizeCalc rsc)
1591
sealed class EventPtrTable : Table<int>
1593
internal const int Index = 0x13;
1595
internal override void Read(MetadataReader mr)
1597
for (int i = 0; i < records.Length; i++)
1599
records[i] = mr.ReadEvent();
1604
sealed class EventTable : Table<EventTable.Record>
1606
internal const int Index = 0x14;
1608
internal struct Record
1610
internal short EventFlags;
1612
internal int EventType;
1615
internal override void Read(MetadataReader mr)
1617
for (int i = 0; i < records.Length; i++)
1619
records[i].EventFlags = mr.ReadInt16();
1620
records[i].Name = mr.ReadStringIndex();
1621
records[i].EventType = mr.ReadTypeDefOrRef();
1625
internal override void Write(MetadataWriter mw)
1627
for (int i = 0; i < rowCount; i++)
1629
mw.Write(records[i].EventFlags);
1630
mw.WriteStringIndex(records[i].Name);
1631
mw.WriteTypeDefOrRef(records[i].EventType);
1635
protected override int GetRowSize(RowSizeCalc rsc)
1640
.WriteTypeDefOrRef()
1645
sealed class PropertyMapTable : SortedTable<PropertyMapTable.Record>
1647
internal const int Index = 0x15;
1649
internal struct Record : IRecord
1651
internal int Parent;
1652
internal int PropertyList;
1656
get { return Parent; }
1659
int IRecord.FilterKey
1661
get { return Parent; }
1665
internal override void Read(MetadataReader mr)
1667
for (int i = 0; i < records.Length; i++)
1669
records[i].Parent = mr.ReadTypeDef();
1670
records[i].PropertyList = mr.ReadProperty();
1674
internal override void Write(MetadataWriter mw)
1676
for (int i = 0; i < rowCount; i++)
1678
mw.WriteTypeDef(records[i].Parent);
1679
mw.WriteProperty(records[i].PropertyList);
1683
protected override int GetRowSize(RowSizeCalc rsc)
1692
sealed class PropertyPtrTable : Table<int>
1694
internal const int Index = 0x16;
1696
internal override void Read(MetadataReader mr)
1698
for (int i = 0; i < records.Length; i++)
1700
records[i] = mr.ReadProperty();
1705
sealed class PropertyTable : Table<PropertyTable.Record>
1707
internal const int Index = 0x17;
1709
internal struct Record
1711
internal short Flags;
1716
internal override void Read(MetadataReader mr)
1718
for (int i = 0; i < records.Length; i++)
1720
records[i].Flags = mr.ReadInt16();
1721
records[i].Name = mr.ReadStringIndex();
1722
records[i].Type = mr.ReadBlobIndex();
1726
internal override void Write(MetadataWriter mw)
1728
for (int i = 0; i < rowCount; i++)
1730
mw.Write(records[i].Flags);
1731
mw.WriteStringIndex(records[i].Name);
1732
mw.WriteBlobIndex(records[i].Type);
1736
protected override int GetRowSize(RowSizeCalc rsc)
1746
sealed class MethodSemanticsTable : SortedTable<MethodSemanticsTable.Record>
1748
internal const int Index = 0x18;
1751
internal const short Setter = 0x0001;
1752
internal const short Getter = 0x0002;
1753
internal const short Other = 0x0004;
1754
internal const short AddOn = 0x0008;
1755
internal const short RemoveOn = 0x0010;
1756
internal const short Fire = 0x0020;
1758
internal struct Record : IRecord
1760
internal short Semantics;
1761
internal int Method;
1762
internal int Association;
1766
get { return Association; }
1769
int IRecord.FilterKey
1771
get { return Association; }
1775
internal override void Read(MetadataReader mr)
1777
for (int i = 0; i < records.Length; i++)
1779
records[i].Semantics = mr.ReadInt16();
1780
records[i].Method = mr.ReadMethodDef();
1781
records[i].Association = mr.ReadHasSemantics();
1785
internal override void Write(MetadataWriter mw)
1787
for (int i = 0; i < rowCount; i++)
1789
mw.Write(records[i].Semantics);
1790
mw.WriteMethodDef(records[i].Method);
1791
mw.WriteHasSemantics(records[i].Association);
1795
protected override int GetRowSize(RowSizeCalc rsc)
1800
.WriteHasSemantics()
1804
internal void Fixup(ModuleBuilder moduleBuilder)
1806
for (int i = 0; i < rowCount; i++)
1808
moduleBuilder.FixupPseudoToken(ref records[i].Method);
1809
int token = records[i].Association;
1810
// do the HasSemantics encoding, so that we can sort the table
1811
switch (token >> 24)
1813
case EventTable.Index:
1814
token = (token & 0xFFFFFF) << 1 | 0;
1816
case PropertyTable.Index:
1817
token = (token & 0xFFFFFF) << 1 | 1;
1820
throw new InvalidOperationException();
1822
records[i].Association = token;
1827
internal MethodInfo GetMethod(Module module, int token, bool nonPublic, short semantics)
1829
foreach (int i in Filter(token))
1831
if ((records[i].Semantics & semantics) != 0)
1833
MethodBase method = module.ResolveMethod((MethodDefTable.Index << 24) + records[i].Method);
1834
if (nonPublic || method.IsPublic)
1836
return (MethodInfo)method;
1843
internal MethodInfo[] GetMethods(Module module, int token, bool nonPublic, short semantics)
1845
List<MethodInfo> methods = new List<MethodInfo>();
1846
foreach (int i in Filter(token))
1848
if ((records[i].Semantics & semantics) != 0)
1850
MethodInfo method = (MethodInfo)module.ResolveMethod((MethodDefTable.Index << 24) + records[i].Method);
1851
if (nonPublic || method.IsPublic)
1853
methods.Add(method);
1857
return methods.ToArray();
1860
internal void ComputeFlags(Module module, int token, out bool isPublic, out bool isNonPrivate, out bool isStatic)
1863
isNonPrivate = false;
1865
foreach (int i in Filter(token))
1867
MethodBase method = module.ResolveMethod((MethodDefTable.Index << 24) + records[i].Method);
1868
isPublic |= method.IsPublic;
1869
isNonPrivate |= (method.Attributes & MethodAttributes.MemberAccessMask) > MethodAttributes.Private;
1870
isStatic |= method.IsStatic;
1875
sealed class MethodImplTable : SortedTable<MethodImplTable.Record>
1877
internal const int Index = 0x19;
1879
internal struct Record : IRecord
1882
internal int MethodBody;
1883
internal int MethodDeclaration;
1887
get { return Class; }
1890
int IRecord.FilterKey
1892
get { return Class; }
1896
internal override void Read(MetadataReader mr)
1898
for (int i = 0; i < records.Length; i++)
1900
records[i].Class = mr.ReadTypeDef();
1901
records[i].MethodBody = mr.ReadMethodDefOrRef();
1902
records[i].MethodDeclaration = mr.ReadMethodDefOrRef();
1906
internal override void Write(MetadataWriter mw)
1908
for (int i = 0; i < rowCount; i++)
1910
mw.WriteTypeDef(records[i].Class);
1911
mw.WriteMethodDefOrRef(records[i].MethodBody);
1912
mw.WriteMethodDefOrRef(records[i].MethodDeclaration);
1916
protected override int GetRowSize(RowSizeCalc rsc)
1920
.WriteMethodDefOrRef()
1921
.WriteMethodDefOrRef()
1925
internal void Fixup(ModuleBuilder moduleBuilder)
1927
for (int i = 0; i < rowCount; i++)
1929
moduleBuilder.FixupPseudoToken(ref records[i].MethodBody);
1930
moduleBuilder.FixupPseudoToken(ref records[i].MethodDeclaration);
1936
sealed class ModuleRefTable : Table<int>
1938
internal const int Index = 0x1A;
1940
internal override void Read(MetadataReader mr)
1942
for (int i = 0; i < records.Length; i++)
1944
records[i] = mr.ReadStringIndex();
1948
internal override void Write(MetadataWriter mw)
1950
for (int i = 0; i < rowCount; i++)
1952
mw.WriteStringIndex(records[i]);
1956
protected override int GetRowSize(RowSizeCalc rsc)
1963
internal int FindOrAddRecord(int str)
1965
for (int i = 0; i < rowCount; i++)
1967
if (records[i] == str)
1972
return AddRecord(str);
1976
sealed class TypeSpecTable : Table<int>
1978
internal const int Index = 0x1B;
1980
internal override void Read(MetadataReader mr)
1982
for (int i = 0; i < records.Length; i++)
1984
records[i] = mr.ReadBlobIndex();
1988
internal override void Write(MetadataWriter mw)
1990
for (int i = 0; i < rowCount; i++)
1992
mw.WriteBlobIndex(records[i]);
1996
protected override int GetRowSize(Table.RowSizeCalc rsc)
1998
return rsc.WriteBlobIndex().Value;
2002
sealed class ImplMapTable : SortedTable<ImplMapTable.Record>
2004
internal const int Index = 0x1C;
2006
internal struct Record : IRecord
2008
internal short MappingFlags;
2009
internal int MemberForwarded;
2010
internal int ImportName;
2011
internal int ImportScope;
2015
get { return MemberForwarded; }
2018
int IRecord.FilterKey
2020
get { return MemberForwarded; }
2024
internal override void Read(MetadataReader mr)
2026
for (int i = 0; i < records.Length; i++)
2028
records[i].MappingFlags = mr.ReadInt16();
2029
records[i].MemberForwarded = mr.ReadMemberForwarded();
2030
records[i].ImportName = mr.ReadStringIndex();
2031
records[i].ImportScope = mr.ReadModuleRef();
2035
internal override void Write(MetadataWriter mw)
2037
for (int i = 0; i < rowCount; i++)
2039
mw.Write(records[i].MappingFlags);
2040
mw.WriteMemberForwarded(records[i].MemberForwarded);
2041
mw.WriteStringIndex(records[i].ImportName);
2042
mw.WriteModuleRef(records[i].ImportScope);
2046
protected override int GetRowSize(RowSizeCalc rsc)
2050
.WriteMemberForwarded()
2056
internal void Fixup(ModuleBuilder moduleBuilder)
2058
for (int i = 0; i < rowCount; i++)
2060
moduleBuilder.FixupPseudoToken(ref records[i].MemberForwarded);
2066
sealed class FieldRVATable : SortedTable<FieldRVATable.Record>
2068
internal const int Index = 0x1D;
2070
internal struct Record : IRecord
2072
internal int RVA; // we set the high bit to signify that the RVA is in the CIL stream (instead of .sdata)
2077
get { return Field; }
2080
int IRecord.FilterKey
2082
get { return Field; }
2086
internal override void Read(MetadataReader mr)
2088
for (int i = 0; i < records.Length; i++)
2090
records[i].RVA = mr.ReadInt32();
2091
records[i].Field = mr.ReadField();
2095
internal override void Write(MetadataWriter mw)
2097
for (int i = 0; i < rowCount; i++)
2099
mw.Write(records[i].RVA);
2100
mw.WriteField(records[i].Field);
2104
protected override int GetRowSize(RowSizeCalc rsc)
2112
internal void Fixup(ModuleBuilder moduleBuilder, int sdataRVA, int cilRVA)
2114
for (int i = 0; i < rowCount; i++)
2116
if (records[i].RVA < 0)
2118
records[i].RVA = (records[i].RVA & 0x7fffffff) + cilRVA;
2122
records[i].RVA += sdataRVA;
2124
moduleBuilder.FixupPseudoToken(ref records[i].Field);
2130
sealed class AssemblyTable : Table<AssemblyTable.Record>
2132
internal const int Index = 0x20;
2134
internal struct Record
2136
internal int HashAlgId;
2137
internal ushort MajorVersion;
2138
internal ushort MinorVersion;
2139
internal ushort BuildNumber;
2140
internal ushort RevisionNumber;
2142
internal int PublicKey;
2144
internal int Culture;
2147
internal override void Read(MetadataReader mr)
2149
for (int i = 0; i < records.Length; i++)
2151
records[i].HashAlgId = mr.ReadInt32();
2152
records[i].MajorVersion = mr.ReadUInt16();
2153
records[i].MinorVersion = mr.ReadUInt16();
2154
records[i].BuildNumber = mr.ReadUInt16();
2155
records[i].RevisionNumber = mr.ReadUInt16();
2156
records[i].Flags = mr.ReadInt32();
2157
records[i].PublicKey = mr.ReadBlobIndex();
2158
records[i].Name = mr.ReadStringIndex();
2159
records[i].Culture = mr.ReadStringIndex();
2163
internal override void Write(MetadataWriter mw)
2165
for (int i = 0; i < rowCount; i++)
2167
mw.Write(records[i].HashAlgId);
2168
mw.Write(records[i].MajorVersion);
2169
mw.Write(records[i].MinorVersion);
2170
mw.Write(records[i].BuildNumber);
2171
mw.Write(records[i].RevisionNumber);
2172
mw.Write(records[i].Flags);
2173
mw.WriteBlobIndex(records[i].PublicKey);
2174
mw.WriteStringIndex(records[i].Name);
2175
mw.WriteStringIndex(records[i].Culture);
2179
protected override int GetRowSize(RowSizeCalc rsc)
2190
sealed class AssemblyRefTable : Table<AssemblyRefTable.Record>
2192
internal const int Index = 0x23;
2194
internal struct Record
2196
internal ushort MajorVersion;
2197
internal ushort MinorVersion;
2198
internal ushort BuildNumber;
2199
internal ushort RevisionNumber;
2201
internal int PublicKeyOrToken;
2203
internal int Culture;
2204
internal int HashValue;
2207
internal int FindOrAddRecord(Record rec)
2209
for (int i = 0; i < rowCount; i++)
2211
// note that we ignore HashValue here!
2212
if (records[i].Name == rec.Name
2213
&& records[i].MajorVersion == rec.MajorVersion
2214
&& records[i].MinorVersion == rec.MinorVersion
2215
&& records[i].BuildNumber == rec.BuildNumber
2216
&& records[i].RevisionNumber == rec.RevisionNumber
2217
&& records[i].Flags == rec.Flags
2218
&& records[i].PublicKeyOrToken == rec.PublicKeyOrToken
2219
&& records[i].Culture == rec.Culture
2225
return AddRecord(rec);
2228
internal override void Read(MetadataReader mr)
2230
for (int i = 0; i < records.Length; i++)
2232
records[i].MajorVersion = mr.ReadUInt16();
2233
records[i].MinorVersion = mr.ReadUInt16();
2234
records[i].BuildNumber = mr.ReadUInt16();
2235
records[i].RevisionNumber = mr.ReadUInt16();
2236
records[i].Flags = mr.ReadInt32();
2237
records[i].PublicKeyOrToken = mr.ReadBlobIndex();
2238
records[i].Name = mr.ReadStringIndex();
2239
records[i].Culture = mr.ReadStringIndex();
2240
records[i].HashValue = mr.ReadBlobIndex();
2244
internal override void Write(MetadataWriter mw)
2246
for (int i = 0; i < rowCount; i++)
2248
mw.Write(records[i].MajorVersion);
2249
mw.Write(records[i].MinorVersion);
2250
mw.Write(records[i].BuildNumber);
2251
mw.Write(records[i].RevisionNumber);
2252
mw.Write(records[i].Flags);
2253
mw.WriteBlobIndex(records[i].PublicKeyOrToken);
2254
mw.WriteStringIndex(records[i].Name);
2255
mw.WriteStringIndex(records[i].Culture);
2256
mw.WriteBlobIndex(records[i].HashValue);
2260
protected override int GetRowSize(RowSizeCalc rsc)
2272
sealed class FileTable : Table<FileTable.Record>
2274
internal const int Index = 0x26;
2276
internal struct Record
2280
internal int HashValue;
2283
internal override void Read(MetadataReader mr)
2285
for (int i = 0; i < records.Length; i++)
2287
records[i].Flags = mr.ReadInt32();
2288
records[i].Name = mr.ReadStringIndex();
2289
records[i].HashValue = mr.ReadBlobIndex();
2293
internal override void Write(MetadataWriter mw)
2295
for (int i = 0; i < rowCount; i++)
2297
mw.Write(records[i].Flags);
2298
mw.WriteStringIndex(records[i].Name);
2299
mw.WriteBlobIndex(records[i].HashValue);
2303
protected override int GetRowSize(RowSizeCalc rsc)
2313
sealed class ExportedTypeTable : Table<ExportedTypeTable.Record>
2315
internal const int Index = 0x27;
2317
internal struct Record
2320
internal int TypeDefId;
2321
internal int TypeName;
2322
internal int TypeNamespace;
2323
internal int Implementation;
2326
internal override void Read(MetadataReader mr)
2328
for (int i = 0; i < records.Length; i++)
2330
records[i].Flags = mr.ReadInt32();
2331
records[i].TypeDefId = mr.ReadInt32();
2332
records[i].TypeName = mr.ReadStringIndex();
2333
records[i].TypeNamespace = mr.ReadStringIndex();
2334
records[i].Implementation = mr.ReadImplementation();
2338
internal override void Write(MetadataWriter mw)
2340
for (int i = 0; i < rowCount; i++)
2342
mw.Write(records[i].Flags);
2343
mw.Write(records[i].TypeDefId);
2344
mw.WriteStringIndex(records[i].TypeName);
2345
mw.WriteStringIndex(records[i].TypeNamespace);
2346
mw.WriteImplementation(records[i].Implementation);
2350
protected override int GetRowSize(RowSizeCalc rsc)
2356
.WriteImplementation()
2360
internal int FindOrAddRecord(Record rec)
2362
for (int i = 0; i < rowCount; i++)
2364
if (records[i].Implementation == rec.Implementation
2365
&& records[i].TypeName == rec.TypeName
2366
&& records[i].TypeNamespace == rec.TypeNamespace)
2371
return AddRecord(rec);
2374
internal void Fixup(ModuleBuilder moduleBuilder)
2376
for (int i = 0; i < rowCount; i++)
2378
moduleBuilder.FixupPseudoToken(ref records[i].Implementation);
2383
sealed class ManifestResourceTable : Table<ManifestResourceTable.Record>
2385
internal const int Index = 0x28;
2387
internal struct Record
2389
internal int Offset;
2392
internal int Implementation;
2395
internal override void Read(MetadataReader mr)
2397
for (int i = 0; i < records.Length; i++)
2399
records[i].Offset = mr.ReadInt32();
2400
records[i].Flags = mr.ReadInt32();
2401
records[i].Name = mr.ReadStringIndex();
2402
records[i].Implementation = mr.ReadImplementation();
2406
internal override void Write(MetadataWriter mw)
2408
for (int i = 0; i < rowCount; i++)
2410
mw.Write(records[i].Offset);
2411
mw.Write(records[i].Flags);
2412
mw.WriteStringIndex(records[i].Name);
2413
mw.WriteImplementation(records[i].Implementation);
2417
protected override int GetRowSize(RowSizeCalc rsc)
2422
.WriteImplementation()
2426
internal void Fixup(ModuleBuilder moduleBuilder)
2428
for (int i = 0; i < rowCount; i++)
2430
moduleBuilder.FixupPseudoToken(ref records[i].Implementation);
2435
sealed class NestedClassTable : SortedTable<NestedClassTable.Record>
2437
internal const int Index = 0x29;
2439
internal struct Record : IRecord
2441
internal int NestedClass;
2442
internal int EnclosingClass;
2446
get { return NestedClass; }
2449
int IRecord.FilterKey
2451
get { return NestedClass; }
2455
internal override void Read(MetadataReader mr)
2457
for (int i = 0; i < records.Length; i++)
2459
records[i].NestedClass = mr.ReadTypeDef();
2460
records[i].EnclosingClass = mr.ReadTypeDef();
2464
internal override void Write(MetadataWriter mw)
2466
for (int i = 0; i < rowCount; i++)
2468
mw.WriteTypeDef(records[i].NestedClass);
2469
mw.WriteTypeDef(records[i].EnclosingClass);
2473
protected override int GetRowSize(RowSizeCalc rsc)
2481
internal List<int> GetNestedClasses(int enclosingClass)
2483
List<int> nestedClasses = new List<int>();
2484
for (int i = 0; i < rowCount; i++)
2486
if (records[i].EnclosingClass == enclosingClass)
2488
nestedClasses.Add(records[i].NestedClass);
2491
return nestedClasses;
2495
sealed class GenericParamTable : SortedTable<GenericParamTable.Record>, IComparer<GenericParamTable.Record>
2497
internal const int Index = 0x2A;
2499
internal struct Record : IRecord
2501
internal short Number;
2502
internal short Flags;
2505
// not part of the table, we use it to be able to fixup the GenericParamConstraint table
2506
internal int unsortedIndex;
2510
get { return Owner; }
2513
int IRecord.FilterKey
2515
get { return Owner; }
2519
internal override void Read(MetadataReader mr)
2521
for (int i = 0; i < records.Length; i++)
2523
records[i].Number = mr.ReadInt16();
2524
records[i].Flags = mr.ReadInt16();
2525
records[i].Owner = mr.ReadTypeOrMethodDef();
2526
records[i].Name = mr.ReadStringIndex();
2530
internal override void Write(MetadataWriter mw)
2532
for (int i = 0; i < rowCount; i++)
2534
mw.Write(records[i].Number);
2535
mw.Write(records[i].Flags);
2536
mw.WriteTypeOrMethodDef(records[i].Owner);
2537
mw.WriteStringIndex(records[i].Name);
2541
protected override int GetRowSize(RowSizeCalc rsc)
2545
.WriteTypeOrMethodDef()
2550
internal void Fixup(ModuleBuilder moduleBuilder)
2552
for (int i = 0; i < rowCount; i++)
2554
int token = records[i].Owner;
2555
moduleBuilder.FixupPseudoToken(ref token);
2556
// do the TypeOrMethodDef encoding, so that we can sort the table
2557
switch (token >> 24)
2559
case TypeDefTable.Index:
2560
records[i].Owner = (token & 0xFFFFFF) << 1 | 0;
2562
case MethodDefTable.Index:
2563
records[i].Owner = (token & 0xFFFFFF) << 1 | 1;
2566
throw new InvalidOperationException();
2568
records[i].unsortedIndex = i;
2570
// FXBUG the unnecessary (IComparer<Record>) cast is a workaround for a .NET 2.0 C# compiler bug
2571
Array.Sort(records, 0, rowCount, (IComparer<Record>)this);
2574
int IComparer<Record>.Compare(Record x, Record y)
2576
if (x.Owner == y.Owner)
2578
return x.Number == y.Number ? 0 : (x.Number > y.Number ? 1 : -1);
2580
return x.Owner > y.Owner ? 1 : -1;
2583
internal void PatchAttribute(int token, GenericParameterAttributes genericParameterAttributes)
2585
records[(token & 0xFFFFFF) - 1].Flags = (short)genericParameterAttributes;
2588
internal int[] GetIndexFixup()
2590
int[] array = new int[rowCount];
2591
for (int i = 0; i < rowCount; i++)
2593
array[records[i].unsortedIndex] = i;
2598
internal int FindFirstByOwner(int token)
2600
foreach (int i in Filter(token))
2608
sealed class MethodSpecTable : Table<MethodSpecTable.Record>
2610
internal const int Index = 0x2B;
2612
internal struct Record
2614
internal int Method;
2615
internal int Instantiation;
2618
internal override void Read(MetadataReader mr)
2620
for (int i = 0; i < records.Length; i++)
2622
records[i].Method = mr.ReadMethodDefOrRef();
2623
records[i].Instantiation = mr.ReadBlobIndex();
2627
internal override void Write(MetadataWriter mw)
2629
for (int i = 0; i < rowCount; i++)
2631
mw.WriteMethodDefOrRef(records[i].Method);
2632
mw.WriteBlobIndex(records[i].Instantiation);
2636
protected override int GetRowSize(RowSizeCalc rsc)
2639
.WriteMethodDefOrRef()
2644
internal int FindOrAddRecord(Record record)
2646
for (int i = 0; i < rowCount; i++)
2648
if (records[i].Method == record.Method
2649
&& records[i].Instantiation == record.Instantiation)
2654
return AddRecord(record);
2657
internal void Fixup(ModuleBuilder moduleBuilder)
2659
for (int i = 0; i < rowCount; i++)
2661
moduleBuilder.FixupPseudoToken(ref records[i].Method);
2666
sealed class GenericParamConstraintTable : SortedTable<GenericParamConstraintTable.Record>
2668
internal const int Index = 0x2C;
2670
internal struct Record : IRecord
2673
internal int Constraint;
2677
get { return Owner; }
2680
int IRecord.FilterKey
2682
get { return Owner; }
2686
internal override void Read(MetadataReader mr)
2688
for (int i = 0; i < records.Length; i++)
2690
records[i].Owner = mr.ReadGenericParam();
2691
records[i].Constraint = mr.ReadTypeDefOrRef();
2695
internal override void Write(MetadataWriter mw)
2697
for (int i = 0; i < rowCount; i++)
2699
mw.WriteGenericParam(records[i].Owner);
2700
mw.WriteTypeDefOrRef(records[i].Constraint);
2704
protected override int GetRowSize(RowSizeCalc rsc)
2707
.WriteGenericParam()
2708
.WriteTypeDefOrRef()
2712
internal void Fixup(ModuleBuilder moduleBuilder)
2714
int[] fixups = moduleBuilder.GenericParam.GetIndexFixup();
2715
for (int i = 0; i < rowCount; i++)
2717
records[i].Owner = fixups[records[i].Owner - 1] + 1;