~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/ikvm/reflect/Metadata/Tables.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  Copyright (C) 2009-2012 Jeroen Frijters
 
3
 
 
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.
 
7
 
 
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:
 
11
 
 
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.
 
19
 
 
20
  Jeroen Frijters
 
21
  jeroen@frijters.net
 
22
  
 
23
*/
 
24
using System;
 
25
using System.Collections.Generic;
 
26
using System.Text;
 
27
using IKVM.Reflection.Emit;
 
28
using IKVM.Reflection.Writer;
 
29
using IKVM.Reflection.Reader;
 
30
 
 
31
namespace IKVM.Reflection.Metadata
 
32
{
 
33
        internal abstract class Table
 
34
        {
 
35
                internal bool Sorted;
 
36
 
 
37
                internal bool IsBig
 
38
                {
 
39
                        get { return RowCount > 65535; }
 
40
                }
 
41
 
 
42
                internal abstract int RowCount { get; set; }
 
43
 
 
44
                internal abstract void Write(MetadataWriter mw);
 
45
                internal abstract void Read(MetadataReader mr);
 
46
 
 
47
                internal int GetLength(MetadataWriter md)
 
48
                {
 
49
                        return RowCount * GetRowSize(new RowSizeCalc(md));
 
50
                }
 
51
 
 
52
                protected abstract int GetRowSize(RowSizeCalc rsc);
 
53
 
 
54
                protected sealed class RowSizeCalc
 
55
                {
 
56
                        private readonly MetadataWriter mw;
 
57
                        private int size;
 
58
 
 
59
                        internal RowSizeCalc(MetadataWriter mw)
 
60
                        {
 
61
                                this.mw = mw;
 
62
                        }
 
63
 
 
64
                        internal RowSizeCalc AddFixed(int size)
 
65
                        {
 
66
                                this.size += size;
 
67
                                return this;
 
68
                        }
 
69
 
 
70
                        internal RowSizeCalc WriteStringIndex()
 
71
                        {
 
72
                                if (mw.bigStrings)
 
73
                                {
 
74
                                        this.size += 4;
 
75
                                }
 
76
                                else
 
77
                                {
 
78
                                        this.size += 2;
 
79
                                }
 
80
                                return this;
 
81
                        }
 
82
 
 
83
                        internal RowSizeCalc WriteGuidIndex()
 
84
                        {
 
85
                                if (mw.bigGuids)
 
86
                                {
 
87
                                        this.size += 4;
 
88
                                }
 
89
                                else
 
90
                                {
 
91
                                        this.size += 2;
 
92
                                }
 
93
                                return this;
 
94
                        }
 
95
 
 
96
                        internal RowSizeCalc WriteBlobIndex()
 
97
                        {
 
98
                                if (mw.bigBlobs)
 
99
                                {
 
100
                                        this.size += 4;
 
101
                                }
 
102
                                else
 
103
                                {
 
104
                                        this.size += 2;
 
105
                                }
 
106
                                return this;
 
107
                        }
 
108
 
 
109
                        internal RowSizeCalc WriteTypeDefOrRef()
 
110
                        {
 
111
                                if (mw.bigTypeDefOrRef)
 
112
                                {
 
113
                                        this.size += 4;
 
114
                                }
 
115
                                else
 
116
                                {
 
117
                                        this.size += 2;
 
118
                                }
 
119
                                return this;
 
120
                        }
 
121
 
 
122
                        internal RowSizeCalc WriteField()
 
123
                        {
 
124
                                if (mw.bigField)
 
125
                                {
 
126
                                        size += 4;
 
127
                                }
 
128
                                else
 
129
                                {
 
130
                                        size += 2;
 
131
                                }
 
132
                                return this;
 
133
                        }
 
134
 
 
135
                        internal RowSizeCalc WriteMethodDef()
 
136
                        {
 
137
                                if (mw.bigMethodDef)
 
138
                                {
 
139
                                        this.size += 4;
 
140
                                }
 
141
                                else
 
142
                                {
 
143
                                        this.size += 2;
 
144
                                }
 
145
                                return this;
 
146
                        }
 
147
 
 
148
                        internal RowSizeCalc WriteParam()
 
149
                        {
 
150
                                if (mw.bigParam)
 
151
                                {
 
152
                                        this.size += 4;
 
153
                                }
 
154
                                else
 
155
                                {
 
156
                                        this.size += 2;
 
157
                                }
 
158
                                return this;
 
159
                        }
 
160
 
 
161
                        internal RowSizeCalc WriteResolutionScope()
 
162
                        {
 
163
                                if (mw.bigResolutionScope)
 
164
                                {
 
165
                                        this.size += 4;
 
166
                                }
 
167
                                else
 
168
                                {
 
169
                                        this.size += 2;
 
170
                                }
 
171
                                return this;
 
172
                        }
 
173
 
 
174
                        internal RowSizeCalc WriteMemberRefParent()
 
175
                        {
 
176
                                if (mw.bigMemberRefParent)
 
177
                                {
 
178
                                        this.size += 4;
 
179
                                }
 
180
                                else
 
181
                                {
 
182
                                        this.size += 2;
 
183
                                }
 
184
                                return this;
 
185
                        }
 
186
 
 
187
                        internal RowSizeCalc WriteHasCustomAttribute()
 
188
                        {
 
189
                                if (mw.bigHasCustomAttribute)
 
190
                                {
 
191
                                        size += 4;
 
192
                                }
 
193
                                else
 
194
                                {
 
195
                                        size += 2;
 
196
                                }
 
197
                                return this;
 
198
                        }
 
199
 
 
200
                        internal RowSizeCalc WriteCustomAttributeType()
 
201
                        {
 
202
                                if (mw.bigCustomAttributeType)
 
203
                                {
 
204
                                        this.size += 4;
 
205
                                }
 
206
                                else
 
207
                                {
 
208
                                        this.size += 2;
 
209
                                }
 
210
                                return this;
 
211
                        }
 
212
 
 
213
                        internal RowSizeCalc WriteHasConstant()
 
214
                        {
 
215
                                if (mw.bigHasConstant)
 
216
                                {
 
217
                                        size += 4;
 
218
                                }
 
219
                                else
 
220
                                {
 
221
                                        size += 2;
 
222
                                }
 
223
                                return this;
 
224
                        }
 
225
 
 
226
                        internal RowSizeCalc WriteTypeDef()
 
227
                        {
 
228
                                if (mw.bigTypeDef)
 
229
                                {
 
230
                                        this.size += 4;
 
231
                                }
 
232
                                else
 
233
                                {
 
234
                                        this.size += 2;
 
235
                                }
 
236
                                return this;
 
237
                        }
 
238
 
 
239
                        internal RowSizeCalc WriteMethodDefOrRef()
 
240
                        {
 
241
                                if (mw.bigMethodDefOrRef)
 
242
                                {
 
243
                                        this.size += 4;
 
244
                                }
 
245
                                else
 
246
                                {
 
247
                                        this.size += 2;
 
248
                                }
 
249
                                return this;
 
250
                        }
 
251
 
 
252
                        internal RowSizeCalc WriteEvent()
 
253
                        {
 
254
                                if (mw.bigEvent)
 
255
                                {
 
256
                                        this.size += 4;
 
257
                                }
 
258
                                else
 
259
                                {
 
260
                                        this.size += 2;
 
261
                                }
 
262
                                return this;
 
263
                        }
 
264
 
 
265
                        internal RowSizeCalc WriteProperty()
 
266
                        {
 
267
                                if (mw.bigProperty)
 
268
                                {
 
269
                                        this.size += 4;
 
270
                                }
 
271
                                else
 
272
                                {
 
273
                                        this.size += 2;
 
274
                                }
 
275
                                return this;
 
276
                        }
 
277
 
 
278
                        internal RowSizeCalc WriteHasSemantics()
 
279
                        {
 
280
                                if (mw.bigHasSemantics)
 
281
                                {
 
282
                                        this.size += 4;
 
283
                                }
 
284
                                else
 
285
                                {
 
286
                                        this.size += 2;
 
287
                                }
 
288
                                return this;
 
289
                        }
 
290
 
 
291
                        internal RowSizeCalc WriteImplementation()
 
292
                        {
 
293
                                if (mw.bigImplementation)
 
294
                                {
 
295
                                        this.size += 4;
 
296
                                }
 
297
                                else
 
298
                                {
 
299
                                        this.size += 2;
 
300
                                }
 
301
                                return this;
 
302
                        }
 
303
 
 
304
                        internal RowSizeCalc WriteTypeOrMethodDef()
 
305
                        {
 
306
                                if (mw.bigTypeOrMethodDef)
 
307
                                {
 
308
                                        this.size += 4;
 
309
                                }
 
310
                                else
 
311
                                {
 
312
                                        this.size += 2;
 
313
                                }
 
314
                                return this;
 
315
                        }
 
316
 
 
317
                        internal RowSizeCalc WriteGenericParam()
 
318
                        {
 
319
                                if (mw.bigGenericParam)
 
320
                                {
 
321
                                        this.size += 4;
 
322
                                }
 
323
                                else
 
324
                                {
 
325
                                        this.size += 2;
 
326
                                }
 
327
                                return this;
 
328
                        }
 
329
 
 
330
                        internal RowSizeCalc WriteHasDeclSecurity()
 
331
                        {
 
332
                                if (mw.bigHasDeclSecurity)
 
333
                                {
 
334
                                        this.size += 4;
 
335
                                }
 
336
                                else
 
337
                                {
 
338
                                        this.size += 2;
 
339
                                }
 
340
                                return this;
 
341
                        }
 
342
 
 
343
                        internal RowSizeCalc WriteMemberForwarded()
 
344
                        {
 
345
                                if (mw.bigMemberForwarded)
 
346
                                {
 
347
                                        this.size += 4;
 
348
                                }
 
349
                                else
 
350
                                {
 
351
                                        this.size += 2;
 
352
                                }
 
353
                                return this;
 
354
                        }
 
355
 
 
356
                        internal RowSizeCalc WriteModuleRef()
 
357
                        {
 
358
                                if (mw.bigModuleRef)
 
359
                                {
 
360
                                        this.size += 4;
 
361
                                }
 
362
                                else
 
363
                                {
 
364
                                        this.size += 2;
 
365
                                }
 
366
                                return this;
 
367
                        }
 
368
 
 
369
                        internal RowSizeCalc WriteHasFieldMarshal()
 
370
                        {
 
371
                                if (mw.bigHasFieldMarshal)
 
372
                                {
 
373
                                        this.size += 4;
 
374
                                }
 
375
                                else
 
376
                                {
 
377
                                        this.size += 2;
 
378
                                }
 
379
                                return this;
 
380
                        }
 
381
 
 
382
                        internal int Value
 
383
                        {
 
384
                                get { return size; }
 
385
                        }
 
386
                }
 
387
        }
 
388
 
 
389
        abstract class Table<T> : Table
 
390
        {
 
391
                internal T[] records = Empty<T>.Array;
 
392
                protected int rowCount;
 
393
 
 
394
                internal sealed override int RowCount
 
395
                {
 
396
                        get { return rowCount; }
 
397
                        set { rowCount = value; records = new T[value]; }
 
398
                }
 
399
 
 
400
                protected override int GetRowSize(RowSizeCalc rsc)
 
401
                {
 
402
                        throw new InvalidOperationException();
 
403
                }
 
404
 
 
405
                internal int AddRecord(T newRecord)
 
406
                {
 
407
                        if (rowCount == records.Length)
 
408
                        {
 
409
                                Array.Resize(ref records, Math.Max(16, records.Length * 2));
 
410
                        }
 
411
                        records[rowCount++] = newRecord;
 
412
                        return rowCount;
 
413
                }
 
414
 
 
415
                internal int AddVirtualRecord()
 
416
                {
 
417
                        return ++rowCount;
 
418
                }
 
419
 
 
420
                internal override void Write(MetadataWriter mw)
 
421
                {
 
422
                        throw new InvalidOperationException();
 
423
                }
 
424
        }
 
425
 
 
426
        abstract class SortedTable<T> : Table<T>
 
427
                where T : SortedTable<T>.IRecord
 
428
        {
 
429
                internal interface IRecord
 
430
                {
 
431
                        int SortKey { get; }
 
432
                        int FilterKey { get; }
 
433
                }
 
434
 
 
435
                internal struct Enumerable
 
436
                {
 
437
                        private readonly SortedTable<T> table;
 
438
                        private readonly int token;
 
439
 
 
440
                        internal Enumerable(SortedTable<T> table, int token)
 
441
                        {
 
442
                                this.table = table;
 
443
                                this.token = token;
 
444
                        }
 
445
 
 
446
                        public Enumerator GetEnumerator()
 
447
                        {
 
448
                                T[] records = table.records;
 
449
                                if (!table.Sorted)
 
450
                                {
 
451
                                        return new Enumerator(records, table.RowCount - 1, -1, token);
 
452
                                }
 
453
                                int index = BinarySearch(records, table.RowCount, token & 0xFFFFFF);
 
454
                                if (index < 0)
 
455
                                {
 
456
                                        return new Enumerator(null, 0, 1, -1);
 
457
                                }
 
458
                                int start = index;
 
459
                                while (start > 0 && (records[start - 1].FilterKey & 0xFFFFFF) == (token & 0xFFFFFF))
 
460
                                {
 
461
                                        start--;
 
462
                                }
 
463
                                int end = index;
 
464
                                int max = table.RowCount - 1;
 
465
                                while (end < max && (records[end + 1].FilterKey & 0xFFFFFF) == (token & 0xFFFFFF))
 
466
                                {
 
467
                                        end++;
 
468
                                }
 
469
                                return new Enumerator(records, end, start - 1, token);
 
470
                        }
 
471
 
 
472
                        private static int BinarySearch(T[] records, int length, int maskedToken)
 
473
                        {
 
474
                                int min = 0;
 
475
                                int max = length - 1;
 
476
                                while (min <= max)
 
477
                                {
 
478
                                        int mid = min + ((max - min) / 2);
 
479
                                        int maskedValue = records[mid].FilterKey & 0xFFFFFF;
 
480
                                        if (maskedToken == maskedValue)
 
481
                                        {
 
482
                                                return mid;
 
483
                                        }
 
484
                                        else if (maskedToken < maskedValue)
 
485
                                        {
 
486
                                                max = mid - 1;
 
487
                                        }
 
488
                                        else
 
489
                                        {
 
490
                                                min = mid + 1;
 
491
                                        }
 
492
                                }
 
493
                                return -1;
 
494
                        }
 
495
                }
 
496
 
 
497
                internal struct Enumerator
 
498
                {
 
499
                        private readonly T[] records;
 
500
                        private readonly int token;
 
501
                        private readonly int max;
 
502
                        private int index;
 
503
 
 
504
                        internal Enumerator(T[] records, int max, int index, int token)
 
505
                        {
 
506
                                this.records = records;
 
507
                                this.token = token;
 
508
                                this.max = max;
 
509
                                this.index = index;
 
510
                        }
 
511
 
 
512
                        public int Current
 
513
                        {
 
514
                                get { return index; }
 
515
                        }
 
516
 
 
517
                        public bool MoveNext()
 
518
                        {
 
519
                                while (index < max)
 
520
                                {
 
521
                                        index++;
 
522
                                        if (records[index].FilterKey == token)
 
523
                                        {
 
524
                                                return true;
 
525
                                        }
 
526
                                }
 
527
                                return false;
 
528
                        }
 
529
                }
 
530
 
 
531
                internal Enumerable Filter(int token)
 
532
                {
 
533
                        return new Enumerable(this, token);
 
534
                }
 
535
 
 
536
                protected void Sort()
 
537
                {
 
538
                        ulong[] map = new ulong[rowCount];
 
539
                        for (uint i = 0; i < map.Length; i++)
 
540
                        {
 
541
                                map[i] = ((ulong)records[i].SortKey << 32) | i;
 
542
                        }
 
543
                        Array.Sort(map);
 
544
                        T[] newRecords = new T[rowCount];
 
545
                        for (int i = 0; i < map.Length; i++)
 
546
                        {
 
547
                                newRecords[i] = records[(int)map[i]];
 
548
                        }
 
549
                        records = newRecords;
 
550
                }
 
551
        }
 
552
 
 
553
        sealed class ModuleTable : Table<ModuleTable.Record>
 
554
        {
 
555
                internal const int Index = 0x00;
 
556
 
 
557
                internal struct Record
 
558
                {
 
559
                        internal short Generation;
 
560
                        internal int Name; // -> StringHeap
 
561
                        internal int Mvid; // -> GuidHeap
 
562
                        internal int EncId; // -> GuidHeap
 
563
                        internal int EncBaseId; // -> GuidHeap
 
564
                }
 
565
 
 
566
                internal override void Read(MetadataReader mr)
 
567
                {
 
568
                        for (int i = 0; i < records.Length; i++)
 
569
                        {
 
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();
 
575
                        }
 
576
                }
 
577
 
 
578
                internal override void Write(MetadataWriter mw)
 
579
                {
 
580
                        for (int i = 0; i < rowCount; i++)
 
581
                        {
 
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);
 
587
                        }
 
588
                }
 
589
 
 
590
                protected override int GetRowSize(RowSizeCalc rsc)
 
591
                {
 
592
                        return rsc
 
593
                                .AddFixed(2)
 
594
                                .WriteStringIndex()
 
595
                                .WriteGuidIndex()
 
596
                                .WriteGuidIndex()
 
597
                                .WriteGuidIndex()
 
598
                                .Value;
 
599
                }
 
600
 
 
601
                internal void Add(short generation, int name, int mvid, int encid, int encbaseid)
 
602
                {
 
603
                        Record record = new Record();
 
604
                        record.Generation = generation;
 
605
                        record.Name = name;
 
606
                        record.Mvid = mvid;
 
607
                        record.EncId = encid;
 
608
                        record.EncBaseId = encbaseid;
 
609
                        AddRecord(record);
 
610
                }
 
611
        }
 
612
 
 
613
        sealed class TypeRefTable : Table<TypeRefTable.Record>
 
614
        {
 
615
                internal const int Index = 0x01;
 
616
 
 
617
                internal struct Record
 
618
                {
 
619
                        internal int ResolutionScope;
 
620
                        internal int TypeName;
 
621
                        internal int TypeNameSpace;
 
622
                }
 
623
 
 
624
                internal override void Read(MetadataReader mr)
 
625
                {
 
626
                        for (int i = 0; i < records.Length; i++)
 
627
                        {
 
628
                                records[i].ResolutionScope = mr.ReadResolutionScope();
 
629
                                records[i].TypeName = mr.ReadStringIndex();
 
630
                                records[i].TypeNameSpace = mr.ReadStringIndex();
 
631
                        }
 
632
                }
 
633
 
 
634
                internal override void Write(MetadataWriter mw)
 
635
                {
 
636
                        for (int i = 0; i < rowCount; i++)
 
637
                        {
 
638
                                mw.WriteResolutionScope(records[i].ResolutionScope);
 
639
                                mw.WriteStringIndex(records[i].TypeName);
 
640
                                mw.WriteStringIndex(records[i].TypeNameSpace);
 
641
                        }
 
642
                }
 
643
 
 
644
                protected override int GetRowSize(RowSizeCalc rsc)
 
645
                {
 
646
                        return rsc
 
647
                                .WriteResolutionScope()
 
648
                                .WriteStringIndex()
 
649
                                .WriteStringIndex()
 
650
                                .Value;
 
651
                }
 
652
 
 
653
                internal void Fixup(ModuleBuilder moduleBuilder)
 
654
                {
 
655
                        for (int i = 0; i < rowCount; i++)
 
656
                        {
 
657
                                moduleBuilder.FixupPseudoToken(ref records[i].ResolutionScope);
 
658
                        }
 
659
                }
 
660
        }
 
661
 
 
662
        sealed class TypeDefTable : Table<TypeDefTable.Record>
 
663
        {
 
664
                internal const int Index = 0x02;
 
665
 
 
666
                internal struct Record
 
667
                {
 
668
                        internal int Flags;
 
669
                        internal int TypeName;
 
670
                        internal int TypeNamespace;
 
671
                        internal int Extends;
 
672
                        internal int FieldList;
 
673
                        internal int MethodList;
 
674
                }
 
675
 
 
676
                internal override void Read(MetadataReader mr)
 
677
                {
 
678
                        for (int i = 0; i < records.Length; i++)
 
679
                        {
 
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();
 
686
                        }
 
687
                }
 
688
 
 
689
                internal override void Write(MetadataWriter mw)
 
690
                {
 
691
                        mw.ModuleBuilder.WriteTypeDefTable(mw);
 
692
                }
 
693
 
 
694
                internal int AllocToken()
 
695
                {
 
696
                        return 0x02000000 + AddVirtualRecord();
 
697
                }
 
698
 
 
699
                protected override int GetRowSize(RowSizeCalc rsc)
 
700
                {
 
701
                        return rsc
 
702
                                .AddFixed(4)
 
703
                                .WriteStringIndex()
 
704
                                .WriteStringIndex()
 
705
                                .WriteTypeDefOrRef()
 
706
                                .WriteField()
 
707
                                .WriteMethodDef()
 
708
                                .Value;
 
709
                }
 
710
        }
 
711
 
 
712
        sealed class FieldPtrTable : Table<int>
 
713
        {
 
714
                internal const int Index = 0x03;
 
715
 
 
716
                internal override void Read(MetadataReader mr)
 
717
                {
 
718
                        for (int i = 0; i < records.Length; i++)
 
719
                        {
 
720
                                records[i] = mr.ReadField();
 
721
                        }
 
722
                }
 
723
        }
 
724
 
 
725
        sealed class FieldTable : Table<FieldTable.Record>
 
726
        {
 
727
                internal const int Index = 0x04;
 
728
 
 
729
                internal struct Record
 
730
                {
 
731
                        internal short Flags;
 
732
                        internal int Name;
 
733
                        internal int Signature;
 
734
                }
 
735
 
 
736
                internal override void Read(MetadataReader mr)
 
737
                {
 
738
                        for (int i = 0; i < records.Length; i++)
 
739
                        {
 
740
                                records[i].Flags = mr.ReadInt16();
 
741
                                records[i].Name = mr.ReadStringIndex();
 
742
                                records[i].Signature = mr.ReadBlobIndex();
 
743
                        }
 
744
                }
 
745
 
 
746
                internal override void Write(MetadataWriter mw)
 
747
                {
 
748
                        mw.ModuleBuilder.WriteFieldTable(mw);
 
749
                }
 
750
 
 
751
                protected override int GetRowSize(RowSizeCalc rsc)
 
752
                {
 
753
                        return rsc
 
754
                                .AddFixed(2)
 
755
                                .WriteStringIndex()
 
756
                                .WriteBlobIndex()
 
757
                                .Value;
 
758
                }
 
759
        }
 
760
 
 
761
        sealed class MethodPtrTable : Table<int>
 
762
        {
 
763
                internal const int Index = 0x05;
 
764
 
 
765
                internal override void Read(MetadataReader mr)
 
766
                {
 
767
                        for (int i = 0; i < records.Length; i++)
 
768
                        {
 
769
                                records[i] = mr.ReadMethodDef();
 
770
                        }
 
771
                }
 
772
        }
 
773
 
 
774
        sealed class MethodDefTable : Table<MethodDefTable.Record>
 
775
        {
 
776
                internal const int Index = 0x06;
 
777
                private int baseRVA;
 
778
 
 
779
                internal struct Record
 
780
                {
 
781
                        internal int RVA;
 
782
                        internal short ImplFlags;
 
783
                        internal short Flags;
 
784
                        internal int Name;
 
785
                        internal int Signature;
 
786
                        internal int ParamList;
 
787
                }
 
788
 
 
789
                internal override void Read(MetadataReader mr)
 
790
                {
 
791
                        for (int i = 0; i < records.Length; i++)
 
792
                        {
 
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();
 
799
                        }
 
800
                }
 
801
 
 
802
                internal override void Write(MetadataWriter mw)
 
803
                {
 
804
                        mw.ModuleBuilder.WriteMethodDefTable(baseRVA, mw);
 
805
                }
 
806
 
 
807
                protected override int GetRowSize(RowSizeCalc rsc)
 
808
                {
 
809
                        return rsc
 
810
                                .AddFixed(8)
 
811
                                .WriteStringIndex()
 
812
                                .WriteBlobIndex()
 
813
                                .WriteParam()
 
814
                                .Value;
 
815
                }
 
816
 
 
817
                internal void Fixup(TextSection code)
 
818
                {
 
819
                        baseRVA = (int)code.MethodBodiesRVA;
 
820
                }
 
821
        }
 
822
 
 
823
        sealed class ParamPtrTable : Table<int>
 
824
        {
 
825
                internal const int Index = 0x07;
 
826
 
 
827
                internal override void Read(MetadataReader mr)
 
828
                {
 
829
                        for (int i = 0; i < records.Length; i++)
 
830
                        {
 
831
                                records[i] = mr.ReadParam();
 
832
                        }
 
833
                }
 
834
        }
 
835
 
 
836
        sealed class ParamTable : Table<ParamTable.Record>
 
837
        {
 
838
                internal const int Index = 0x08;
 
839
 
 
840
                internal struct Record
 
841
                {
 
842
                        internal short Flags;
 
843
                        internal short Sequence;
 
844
                        internal int Name;
 
845
                }
 
846
 
 
847
                internal override void Read(MetadataReader mr)
 
848
                {
 
849
                        for (int i = 0; i < records.Length; i++)
 
850
                        {
 
851
                                records[i].Flags = mr.ReadInt16();
 
852
                                records[i].Sequence = mr.ReadInt16();
 
853
                                records[i].Name = mr.ReadStringIndex();
 
854
                        }
 
855
                }
 
856
 
 
857
                internal override void Write(MetadataWriter mw)
 
858
                {
 
859
                        mw.ModuleBuilder.WriteParamTable(mw);
 
860
                }
 
861
 
 
862
                protected override int GetRowSize(RowSizeCalc rsc)
 
863
                {
 
864
                        return rsc
 
865
                                .AddFixed(4)
 
866
                                .WriteStringIndex()
 
867
                                .Value;
 
868
                }
 
869
        }
 
870
 
 
871
        sealed class InterfaceImplTable : SortedTable<InterfaceImplTable.Record>
 
872
        {
 
873
                internal const int Index = 0x09;
 
874
 
 
875
                internal struct Record : IRecord
 
876
                {
 
877
                        internal int Class;
 
878
                        internal int Interface;
 
879
 
 
880
                        int IRecord.SortKey
 
881
                        {
 
882
                                get { return Class; }
 
883
                        }
 
884
 
 
885
                        int IRecord.FilterKey
 
886
                        {
 
887
                                get { return Class; }
 
888
                        }
 
889
                }
 
890
 
 
891
                internal override void Read(MetadataReader mr)
 
892
                {
 
893
                        for (int i = 0; i < records.Length; i++)
 
894
                        {
 
895
                                records[i].Class = mr.ReadTypeDef();
 
896
                                records[i].Interface = mr.ReadTypeDefOrRef();
 
897
                        }
 
898
                }
 
899
 
 
900
                internal override void Write(MetadataWriter mw)
 
901
                {
 
902
                        for (int i = 0; i < rowCount; i++)
 
903
                        {
 
904
                                mw.WriteTypeDef(records[i].Class);
 
905
                                mw.WriteEncodedTypeDefOrRef(records[i].Interface);
 
906
                        }
 
907
                }
 
908
 
 
909
                protected override int GetRowSize(RowSizeCalc rsc)
 
910
                {
 
911
                        return rsc
 
912
                                .WriteTypeDef()
 
913
                                .WriteTypeDefOrRef()
 
914
                                .Value;
 
915
                }
 
916
 
 
917
                internal void Fixup()
 
918
                {
 
919
                        for (int i = 0; i < rowCount; i++)
 
920
                        {
 
921
                                int token = records[i].Interface;
 
922
                                switch (token >> 24)
 
923
                                {
 
924
                                        case 0:
 
925
                                                break;
 
926
                                        case TypeDefTable.Index:
 
927
                                                token = (token & 0xFFFFFF) << 2 | 0;
 
928
                                                break;
 
929
                                        case TypeRefTable.Index:
 
930
                                                token = (token & 0xFFFFFF) << 2 | 1;
 
931
                                                break;
 
932
                                        case TypeSpecTable.Index:
 
933
                                                token = (token & 0xFFFFFF) << 2 | 2;
 
934
                                                break;
 
935
                                        default:
 
936
                                                throw new InvalidOperationException();
 
937
                                }
 
938
                                records[i].Interface = token;
 
939
                        }
 
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).
 
943
                        Sort();
 
944
                }
 
945
        }
 
946
 
 
947
        sealed class MemberRefTable : Table<MemberRefTable.Record>
 
948
        {
 
949
                internal const int Index = 0x0A;
 
950
 
 
951
                internal struct Record
 
952
                {
 
953
                        internal int Class;
 
954
                        internal int Name;
 
955
                        internal int Signature;
 
956
                }
 
957
 
 
958
                internal override void Read(MetadataReader mr)
 
959
                {
 
960
                        for (int i = 0; i < records.Length; i++)
 
961
                        {
 
962
                                records[i].Class = mr.ReadMemberRefParent();
 
963
                                records[i].Name = mr.ReadStringIndex();
 
964
                                records[i].Signature = mr.ReadBlobIndex();
 
965
                        }
 
966
                }
 
967
 
 
968
                internal override void Write(MetadataWriter mw)
 
969
                {
 
970
                        for (int i = 0; i < rowCount; i++)
 
971
                        {
 
972
                                mw.WriteMemberRefParent(records[i].Class);
 
973
                                mw.WriteStringIndex(records[i].Name);
 
974
                                mw.WriteBlobIndex(records[i].Signature);
 
975
                        }
 
976
                }
 
977
 
 
978
                protected override int GetRowSize(RowSizeCalc rsc)
 
979
                {
 
980
                        return rsc
 
981
                                .WriteMemberRefParent()
 
982
                                .WriteStringIndex()
 
983
                                .WriteBlobIndex()
 
984
                                .Value;
 
985
                }
 
986
 
 
987
                internal int FindOrAddRecord(Record record)
 
988
                {
 
989
                        for (int i = 0; i < rowCount; i++)
 
990
                        {
 
991
                                if (records[i].Class == record.Class
 
992
                                        && records[i].Name == record.Name
 
993
                                        && records[i].Signature == record.Signature)
 
994
                                {
 
995
                                        return i + 1;
 
996
                                }
 
997
                        }
 
998
                        return AddRecord(record);
 
999
                }
 
1000
 
 
1001
                internal void Fixup(ModuleBuilder moduleBuilder)
 
1002
                {
 
1003
                        for (int i = 0; i < rowCount; i++)
 
1004
                        {
 
1005
                                moduleBuilder.FixupPseudoToken(ref records[i].Class);
 
1006
                        }
 
1007
                }
 
1008
        }
 
1009
 
 
1010
        sealed class ConstantTable : SortedTable<ConstantTable.Record>
 
1011
        {
 
1012
                internal const int Index = 0x0B;
 
1013
 
 
1014
                internal struct Record : IRecord
 
1015
                {
 
1016
                        internal short Type;
 
1017
                        internal int Parent;
 
1018
                        internal int Value;
 
1019
 
 
1020
                        int IRecord.SortKey
 
1021
                        {
 
1022
                                get { return EncodeHasConstant(Parent); }
 
1023
                        }
 
1024
 
 
1025
                        int IRecord.FilterKey
 
1026
                        {
 
1027
                                get { return Parent; }
 
1028
                        }
 
1029
                }
 
1030
 
 
1031
                internal override void Read(MetadataReader mr)
 
1032
                {
 
1033
                        for (int i = 0; i < records.Length; i++)
 
1034
                        {
 
1035
                                records[i].Type = mr.ReadInt16();
 
1036
                                records[i].Parent = mr.ReadHasConstant();
 
1037
                                records[i].Value = mr.ReadBlobIndex();
 
1038
                        }
 
1039
                }
 
1040
 
 
1041
                internal override void Write(MetadataWriter mw)
 
1042
                {
 
1043
                        for (int i = 0; i < rowCount; i++)
 
1044
                        {
 
1045
                                mw.Write(records[i].Type);
 
1046
                                mw.WriteHasConstant(records[i].Parent);
 
1047
                                mw.WriteBlobIndex(records[i].Value);
 
1048
                        }
 
1049
                }
 
1050
 
 
1051
                protected override int GetRowSize(RowSizeCalc rsc)
 
1052
                {
 
1053
                        return rsc
 
1054
                                .AddFixed(2)
 
1055
                                .WriteHasConstant()
 
1056
                                .WriteBlobIndex()
 
1057
                                .Value;
 
1058
                }
 
1059
 
 
1060
                internal void Fixup(ModuleBuilder moduleBuilder)
 
1061
                {
 
1062
                        for (int i = 0; i < rowCount; i++)
 
1063
                        {
 
1064
                                moduleBuilder.FixupPseudoToken(ref records[i].Parent);
 
1065
                        }
 
1066
                        Sort();
 
1067
                }
 
1068
 
 
1069
                internal static int EncodeHasConstant(int token)
 
1070
                {
 
1071
                        switch (token >> 24)
 
1072
                        {
 
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;
 
1079
                                default:
 
1080
                                        throw new InvalidOperationException();
 
1081
                        }
 
1082
                }
 
1083
 
 
1084
                internal object GetRawConstantValue(Module module, int parent)
 
1085
                {
 
1086
                        foreach (int i in Filter(parent))
 
1087
                        {
 
1088
                                ByteReader br = module.GetBlob(module.Constant.records[i].Value);
 
1089
                                switch (module.Constant.records[i].Type)
 
1090
                                {
 
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:
 
1117
                                                {
 
1118
                                                        char[] chars = new char[br.Length / 2];
 
1119
                                                        for (int j = 0; j < chars.Length; j++)
 
1120
                                                        {
 
1121
                                                                chars[j] = br.ReadChar();
 
1122
                                                        }
 
1123
                                                        return new String(chars);
 
1124
                                                }
 
1125
                                        case Signature.ELEMENT_TYPE_CLASS:
 
1126
                                                if (br.ReadInt32() != 0)
 
1127
                                                {
 
1128
                                                        throw new BadImageFormatException();
 
1129
                                                }
 
1130
                                                return null;
 
1131
                                        default:
 
1132
                                                throw new BadImageFormatException();
 
1133
                                }
 
1134
                        }
 
1135
                        throw new InvalidOperationException();
 
1136
                }
 
1137
        }
 
1138
 
 
1139
        sealed class CustomAttributeTable : SortedTable<CustomAttributeTable.Record>
 
1140
        {
 
1141
                internal const int Index = 0x0C;
 
1142
 
 
1143
                internal struct Record : IRecord
 
1144
                {
 
1145
                        internal int Parent;
 
1146
                        internal int Type;
 
1147
                        internal int Value;
 
1148
 
 
1149
                        int IRecord.SortKey
 
1150
                        {
 
1151
                                get { return EncodeHasCustomAttribute(Parent); }
 
1152
                        }
 
1153
 
 
1154
                        int IRecord.FilterKey
 
1155
                        {
 
1156
                                get { return Parent; }
 
1157
                        }
 
1158
                }
 
1159
 
 
1160
                internal override void Read(MetadataReader mr)
 
1161
                {
 
1162
                        for (int i = 0; i < records.Length; i++)
 
1163
                        {
 
1164
                                records[i].Parent = mr.ReadHasCustomAttribute();
 
1165
                                records[i].Type = mr.ReadCustomAttributeType();
 
1166
                                records[i].Value = mr.ReadBlobIndex();
 
1167
                        }
 
1168
                }
 
1169
 
 
1170
                internal override void Write(MetadataWriter mw)
 
1171
                {
 
1172
                        for (int i = 0; i < rowCount; i++)
 
1173
                        {
 
1174
                                mw.WriteHasCustomAttribute(records[i].Parent);
 
1175
                                mw.WriteCustomAttributeType(records[i].Type);
 
1176
                                mw.WriteBlobIndex(records[i].Value);
 
1177
                        }
 
1178
                }
 
1179
 
 
1180
                protected override int GetRowSize(RowSizeCalc rsc)
 
1181
                {
 
1182
                        return rsc
 
1183
                                .WriteHasCustomAttribute()
 
1184
                                .WriteCustomAttributeType()
 
1185
                                .WriteBlobIndex()
 
1186
                                .Value;
 
1187
                }
 
1188
 
 
1189
                internal void Fixup(ModuleBuilder moduleBuilder)
 
1190
                {
 
1191
                        int[] genericParamFixup = moduleBuilder.GenericParam.GetIndexFixup();
 
1192
                        for (int i = 0; i < rowCount; i++)
 
1193
                        {
 
1194
                                moduleBuilder.FixupPseudoToken(ref records[i].Type);
 
1195
                                moduleBuilder.FixupPseudoToken(ref records[i].Parent);
 
1196
                                if (records[i].Parent >> 24 == GenericParamTable.Index)
 
1197
                                {
 
1198
                                        records[i].Parent = (GenericParamTable.Index << 24) + genericParamFixup[(records[i].Parent & 0xFFFFFF) - 1] + 1;
 
1199
                                }
 
1200
                        }
 
1201
                        Sort();
 
1202
                }
 
1203
 
 
1204
                internal static int EncodeHasCustomAttribute(int token)
 
1205
                {
 
1206
                        switch (token >> 24)
 
1207
                        {
 
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;
 
1247
                                default:
 
1248
                                        throw new InvalidOperationException();
 
1249
                        }
 
1250
                }
 
1251
        }
 
1252
 
 
1253
        sealed class FieldMarshalTable : SortedTable<FieldMarshalTable.Record>
 
1254
        {
 
1255
                internal const int Index = 0x0D;
 
1256
 
 
1257
                internal struct Record : IRecord
 
1258
                {
 
1259
                        internal int Parent;
 
1260
                        internal int NativeType;
 
1261
 
 
1262
                        int IRecord.SortKey
 
1263
                        {
 
1264
                                get { return EncodeHasFieldMarshal(Parent); }
 
1265
                        }
 
1266
 
 
1267
                        int IRecord.FilterKey
 
1268
                        {
 
1269
                                get { return Parent; }
 
1270
                        }
 
1271
                }
 
1272
 
 
1273
                internal override void Read(MetadataReader mr)
 
1274
                {
 
1275
                        for (int i = 0; i < records.Length; i++)
 
1276
                        {
 
1277
                                records[i].Parent = mr.ReadHasFieldMarshal();
 
1278
                                records[i].NativeType = mr.ReadBlobIndex();
 
1279
                        }
 
1280
                }
 
1281
 
 
1282
                internal override void Write(MetadataWriter mw)
 
1283
                {
 
1284
                        for (int i = 0; i < rowCount; i++)
 
1285
                        {
 
1286
                                mw.WriteHasFieldMarshal(records[i].Parent);
 
1287
                                mw.WriteBlobIndex(records[i].NativeType);
 
1288
                        }
 
1289
                }
 
1290
 
 
1291
                protected override int GetRowSize(RowSizeCalc rsc)
 
1292
                {
 
1293
                        return rsc
 
1294
                                .WriteHasFieldMarshal()
 
1295
                                .WriteBlobIndex()
 
1296
                                .Value;
 
1297
                }
 
1298
 
 
1299
                internal void Fixup(ModuleBuilder moduleBuilder)
 
1300
                {
 
1301
                        for (int i = 0; i < rowCount; i++)
 
1302
                        {
 
1303
                                records[i].Parent = moduleBuilder.ResolvePseudoToken(records[i].Parent);
 
1304
                        }
 
1305
                        Sort();
 
1306
                }
 
1307
 
 
1308
                internal static int EncodeHasFieldMarshal(int token)
 
1309
                {
 
1310
                        switch (token >> 24)
 
1311
                        {
 
1312
                                case FieldTable.Index:
 
1313
                                        return (token & 0xFFFFFF) << 1 | 0;
 
1314
                                case ParamTable.Index:
 
1315
                                        return (token & 0xFFFFFF) << 1 | 1;
 
1316
                                default:
 
1317
                                        throw new InvalidOperationException();
 
1318
                        }
 
1319
                }
 
1320
        }
 
1321
 
 
1322
        sealed class DeclSecurityTable : SortedTable<DeclSecurityTable.Record>
 
1323
        {
 
1324
                internal const int Index = 0x0E;
 
1325
 
 
1326
                internal struct Record : IRecord
 
1327
                {
 
1328
                        internal short Action;
 
1329
                        internal int Parent;
 
1330
                        internal int PermissionSet;
 
1331
 
 
1332
                        int IRecord.SortKey
 
1333
                        {
 
1334
                                get { return Parent; }
 
1335
                        }
 
1336
 
 
1337
                        int IRecord.FilterKey
 
1338
                        {
 
1339
                                get { return Parent; }
 
1340
                        }
 
1341
                }
 
1342
 
 
1343
                internal override void Read(MetadataReader mr)
 
1344
                {
 
1345
                        for (int i = 0; i < records.Length; i++)
 
1346
                        {
 
1347
                                records[i].Action = mr.ReadInt16();
 
1348
                                records[i].Parent = mr.ReadHasDeclSecurity();
 
1349
                                records[i].PermissionSet = mr.ReadBlobIndex();
 
1350
                        }
 
1351
                }
 
1352
 
 
1353
                internal override void Write(MetadataWriter mw)
 
1354
                {
 
1355
                        for (int i = 0; i < rowCount; i++)
 
1356
                        {
 
1357
                                mw.Write(records[i].Action);
 
1358
                                mw.WriteHasDeclSecurity(records[i].Parent);
 
1359
                                mw.WriteBlobIndex(records[i].PermissionSet);
 
1360
                        }
 
1361
                }
 
1362
 
 
1363
                protected override int GetRowSize(RowSizeCalc rsc)
 
1364
                {
 
1365
                        return rsc
 
1366
                                .AddFixed(2)
 
1367
                                .WriteHasDeclSecurity()
 
1368
                                .WriteBlobIndex()
 
1369
                                .Value;
 
1370
                }
 
1371
 
 
1372
                internal void Fixup(ModuleBuilder moduleBuilder)
 
1373
                {
 
1374
                        for (int i = 0; i < rowCount; i++)
 
1375
                        {
 
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)
 
1380
                                {
 
1381
                                        case TypeDefTable.Index:
 
1382
                                                token = (token & 0xFFFFFF) << 2 | 0;
 
1383
                                                break;
 
1384
                                        case MethodDefTable.Index:
 
1385
                                                token = (token & 0xFFFFFF) << 2 | 1;
 
1386
                                                break;
 
1387
                                        case AssemblyTable.Index:
 
1388
                                                token = (token & 0xFFFFFF) << 2 | 2;
 
1389
                                                break;
 
1390
                                        default:
 
1391
                                                throw new InvalidOperationException();
 
1392
                                }
 
1393
                                records[i].Parent = token;
 
1394
                        }
 
1395
                        Sort();
 
1396
                }
 
1397
        }
 
1398
 
 
1399
        sealed class ClassLayoutTable : SortedTable<ClassLayoutTable.Record>
 
1400
        {
 
1401
                internal const int Index = 0x0f;
 
1402
 
 
1403
                internal struct Record : IRecord
 
1404
                {
 
1405
                        internal short PackingSize;
 
1406
                        internal int ClassSize;
 
1407
                        internal int Parent;
 
1408
 
 
1409
                        int IRecord.SortKey
 
1410
                        {
 
1411
                                get { return Parent; }
 
1412
                        }
 
1413
 
 
1414
                        int IRecord.FilterKey
 
1415
                        {
 
1416
                                get { return Parent; }
 
1417
                        }
 
1418
                }
 
1419
 
 
1420
                internal override void Read(MetadataReader mr)
 
1421
                {
 
1422
                        for (int i = 0; i < records.Length; i++)
 
1423
                        {
 
1424
                                records[i].PackingSize = mr.ReadInt16();
 
1425
                                records[i].ClassSize = mr.ReadInt32();
 
1426
                                records[i].Parent = mr.ReadTypeDef();
 
1427
                        }
 
1428
                }
 
1429
 
 
1430
                internal override void Write(MetadataWriter mw)
 
1431
                {
 
1432
                        Sort();
 
1433
                        for (int i = 0; i < rowCount; i++)
 
1434
                        {
 
1435
                                mw.Write(records[i].PackingSize);
 
1436
                                mw.Write(records[i].ClassSize);
 
1437
                                mw.WriteTypeDef(records[i].Parent);
 
1438
                        }
 
1439
                }
 
1440
 
 
1441
                protected override int GetRowSize(RowSizeCalc rsc)
 
1442
                {
 
1443
                        return rsc
 
1444
                                .AddFixed(6)
 
1445
                                .WriteTypeDef()
 
1446
                                .Value;
 
1447
                }
 
1448
        }
 
1449
 
 
1450
        sealed class FieldLayoutTable : SortedTable<FieldLayoutTable.Record>
 
1451
        {
 
1452
                internal const int Index = 0x10;
 
1453
 
 
1454
                internal struct Record : IRecord
 
1455
                {
 
1456
                        internal int Offset;
 
1457
                        internal int Field;
 
1458
 
 
1459
                        int IRecord.SortKey
 
1460
                        {
 
1461
                                get { return Field; }
 
1462
                        }
 
1463
 
 
1464
                        int IRecord.FilterKey
 
1465
                        {
 
1466
                                get { return Field; }
 
1467
                        }
 
1468
                }
 
1469
 
 
1470
                internal override void Read(MetadataReader mr)
 
1471
                {
 
1472
                        for (int i = 0; i < records.Length; i++)
 
1473
                        {
 
1474
                                records[i].Offset = mr.ReadInt32();
 
1475
                                records[i].Field = mr.ReadField();
 
1476
                        }
 
1477
                }
 
1478
 
 
1479
                internal override void Write(MetadataWriter mw)
 
1480
                {
 
1481
                        for (int i = 0; i < rowCount; i++)
 
1482
                        {
 
1483
                                mw.Write(records[i].Offset);
 
1484
                                mw.WriteField(records[i].Field);
 
1485
                        }
 
1486
                }
 
1487
 
 
1488
                protected override int GetRowSize(RowSizeCalc rsc)
 
1489
                {
 
1490
                        return rsc
 
1491
                                .AddFixed(4)
 
1492
                                .WriteField()
 
1493
                                .Value;
 
1494
                }
 
1495
 
 
1496
                internal void Fixup(ModuleBuilder moduleBuilder)
 
1497
                {
 
1498
                        for (int i = 0; i < rowCount; i++)
 
1499
                        {
 
1500
                                records[i].Field = moduleBuilder.ResolvePseudoToken(records[i].Field) & 0xFFFFFF;
 
1501
                        }
 
1502
                        Sort();
 
1503
                }
 
1504
        }
 
1505
 
 
1506
        sealed class StandAloneSigTable : Table<int>
 
1507
        {
 
1508
                internal const int Index = 0x11;
 
1509
 
 
1510
                internal override void Read(MetadataReader mr)
 
1511
                {
 
1512
                        for (int i = 0; i < records.Length; i++)
 
1513
                        {
 
1514
                                records[i] = mr.ReadBlobIndex();
 
1515
                        }
 
1516
                }
 
1517
 
 
1518
                internal override void Write(MetadataWriter mw)
 
1519
                {
 
1520
                        for (int i = 0; i < rowCount; i++)
 
1521
                        {
 
1522
                                mw.WriteBlobIndex(records[i]);
 
1523
                        }
 
1524
                }
 
1525
 
 
1526
                protected override int GetRowSize(Table.RowSizeCalc rsc)
 
1527
                {
 
1528
                        return rsc.WriteBlobIndex().Value;
 
1529
                }
 
1530
 
 
1531
                internal int FindOrAddRecord(int blob)
 
1532
                {
 
1533
                        for (int i = 0; i < rowCount; i++)
 
1534
                        {
 
1535
                                if (records[i] == blob)
 
1536
                                {
 
1537
                                        return i + 1;
 
1538
                                }
 
1539
                        }
 
1540
                        return AddRecord(blob);
 
1541
                }
 
1542
        }
 
1543
 
 
1544
        sealed class EventMapTable : SortedTable<EventMapTable.Record>
 
1545
        {
 
1546
                internal const int Index = 0x12;
 
1547
 
 
1548
                internal struct Record : IRecord
 
1549
                {
 
1550
                        internal int Parent;
 
1551
                        internal int EventList;
 
1552
 
 
1553
                        int IRecord.SortKey
 
1554
                        {
 
1555
                                get { return Parent; }
 
1556
                        }
 
1557
 
 
1558
                        int IRecord.FilterKey
 
1559
                        {
 
1560
                                get { return Parent; }
 
1561
                        }
 
1562
                }
 
1563
 
 
1564
                internal override void Read(MetadataReader mr)
 
1565
                {
 
1566
                        for (int i = 0; i < records.Length; i++)
 
1567
                        {
 
1568
                                records[i].Parent = mr.ReadTypeDef();
 
1569
                                records[i].EventList = mr.ReadEvent();
 
1570
                        }
 
1571
                }
 
1572
 
 
1573
                internal override void Write(MetadataWriter mw)
 
1574
                {
 
1575
                        for (int i = 0; i < rowCount; i++)
 
1576
                        {
 
1577
                                mw.WriteTypeDef(records[i].Parent);
 
1578
                                mw.WriteEvent(records[i].EventList);
 
1579
                        }
 
1580
                }
 
1581
 
 
1582
                protected override int GetRowSize(RowSizeCalc rsc)
 
1583
                {
 
1584
                        return rsc
 
1585
                                .WriteTypeDef()
 
1586
                                .WriteEvent()
 
1587
                                .Value;
 
1588
                }
 
1589
        }
 
1590
 
 
1591
        sealed class EventPtrTable : Table<int>
 
1592
        {
 
1593
                internal const int Index = 0x13;
 
1594
 
 
1595
                internal override void Read(MetadataReader mr)
 
1596
                {
 
1597
                        for (int i = 0; i < records.Length; i++)
 
1598
                        {
 
1599
                                records[i] = mr.ReadEvent();
 
1600
                        }
 
1601
                }
 
1602
        }
 
1603
 
 
1604
        sealed class EventTable : Table<EventTable.Record>
 
1605
        {
 
1606
                internal const int Index = 0x14;
 
1607
 
 
1608
                internal struct Record
 
1609
                {
 
1610
                        internal short EventFlags;
 
1611
                        internal int Name;
 
1612
                        internal int EventType;
 
1613
                }
 
1614
 
 
1615
                internal override void Read(MetadataReader mr)
 
1616
                {
 
1617
                        for (int i = 0; i < records.Length; i++)
 
1618
                        {
 
1619
                                records[i].EventFlags = mr.ReadInt16();
 
1620
                                records[i].Name = mr.ReadStringIndex();
 
1621
                                records[i].EventType = mr.ReadTypeDefOrRef();
 
1622
                        }
 
1623
                }
 
1624
 
 
1625
                internal override void Write(MetadataWriter mw)
 
1626
                {
 
1627
                        for (int i = 0; i < rowCount; i++)
 
1628
                        {
 
1629
                                mw.Write(records[i].EventFlags);
 
1630
                                mw.WriteStringIndex(records[i].Name);
 
1631
                                mw.WriteTypeDefOrRef(records[i].EventType);
 
1632
                        }
 
1633
                }
 
1634
 
 
1635
                protected override int GetRowSize(RowSizeCalc rsc)
 
1636
                {
 
1637
                        return rsc
 
1638
                                .AddFixed(2)
 
1639
                                .WriteStringIndex()
 
1640
                                .WriteTypeDefOrRef()
 
1641
                                .Value;
 
1642
                }
 
1643
        }
 
1644
 
 
1645
        sealed class PropertyMapTable : SortedTable<PropertyMapTable.Record>
 
1646
        {
 
1647
                internal const int Index = 0x15;
 
1648
 
 
1649
                internal struct Record : IRecord
 
1650
                {
 
1651
                        internal int Parent;
 
1652
                        internal int PropertyList;
 
1653
 
 
1654
                        int IRecord.SortKey
 
1655
                        {
 
1656
                                get { return Parent; }
 
1657
                        }
 
1658
 
 
1659
                        int IRecord.FilterKey
 
1660
                        {
 
1661
                                get { return Parent; }
 
1662
                        }
 
1663
                }
 
1664
 
 
1665
                internal override void Read(MetadataReader mr)
 
1666
                {
 
1667
                        for (int i = 0; i < records.Length; i++)
 
1668
                        {
 
1669
                                records[i].Parent = mr.ReadTypeDef();
 
1670
                                records[i].PropertyList = mr.ReadProperty();
 
1671
                        }
 
1672
                }
 
1673
 
 
1674
                internal override void Write(MetadataWriter mw)
 
1675
                {
 
1676
                        for (int i = 0; i < rowCount; i++)
 
1677
                        {
 
1678
                                mw.WriteTypeDef(records[i].Parent);
 
1679
                                mw.WriteProperty(records[i].PropertyList);
 
1680
                        }
 
1681
                }
 
1682
 
 
1683
                protected override int GetRowSize(RowSizeCalc rsc)
 
1684
                {
 
1685
                        return rsc
 
1686
                                .WriteTypeDef()
 
1687
                                .WriteProperty()
 
1688
                                .Value;
 
1689
                }
 
1690
        }
 
1691
 
 
1692
        sealed class PropertyPtrTable : Table<int>
 
1693
        {
 
1694
                internal const int Index = 0x16;
 
1695
 
 
1696
                internal override void Read(MetadataReader mr)
 
1697
                {
 
1698
                        for (int i = 0; i < records.Length; i++)
 
1699
                        {
 
1700
                                records[i] = mr.ReadProperty();
 
1701
                        }
 
1702
                }
 
1703
        }
 
1704
 
 
1705
        sealed class PropertyTable : Table<PropertyTable.Record>
 
1706
        {
 
1707
                internal const int Index = 0x17;
 
1708
 
 
1709
                internal struct Record
 
1710
                {
 
1711
                        internal short Flags;
 
1712
                        internal int Name;
 
1713
                        internal int Type;
 
1714
                }
 
1715
 
 
1716
                internal override void Read(MetadataReader mr)
 
1717
                {
 
1718
                        for (int i = 0; i < records.Length; i++)
 
1719
                        {
 
1720
                                records[i].Flags = mr.ReadInt16();
 
1721
                                records[i].Name = mr.ReadStringIndex();
 
1722
                                records[i].Type = mr.ReadBlobIndex();
 
1723
                        }
 
1724
                }
 
1725
 
 
1726
                internal override void Write(MetadataWriter mw)
 
1727
                {
 
1728
                        for (int i = 0; i < rowCount; i++)
 
1729
                        {
 
1730
                                mw.Write(records[i].Flags);
 
1731
                                mw.WriteStringIndex(records[i].Name);
 
1732
                                mw.WriteBlobIndex(records[i].Type);
 
1733
                        }
 
1734
                }
 
1735
 
 
1736
                protected override int GetRowSize(RowSizeCalc rsc)
 
1737
                {
 
1738
                        return rsc
 
1739
                                .AddFixed(2)
 
1740
                                .WriteStringIndex()
 
1741
                                .WriteBlobIndex()
 
1742
                                .Value;
 
1743
                }
 
1744
        }
 
1745
 
 
1746
        sealed class MethodSemanticsTable : SortedTable<MethodSemanticsTable.Record>
 
1747
        {
 
1748
                internal const int Index = 0x18;
 
1749
 
 
1750
                // semantics
 
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;
 
1757
 
 
1758
                internal struct Record : IRecord
 
1759
                {
 
1760
                        internal short Semantics;
 
1761
                        internal int Method;
 
1762
                        internal int Association;
 
1763
 
 
1764
                        int IRecord.SortKey
 
1765
                        {
 
1766
                                get { return Association; }
 
1767
                        }
 
1768
 
 
1769
                        int IRecord.FilterKey
 
1770
                        {
 
1771
                                get { return Association; }
 
1772
                        }
 
1773
                }
 
1774
 
 
1775
                internal override void Read(MetadataReader mr)
 
1776
                {
 
1777
                        for (int i = 0; i < records.Length; i++)
 
1778
                        {
 
1779
                                records[i].Semantics = mr.ReadInt16();
 
1780
                                records[i].Method = mr.ReadMethodDef();
 
1781
                                records[i].Association = mr.ReadHasSemantics();
 
1782
                        }
 
1783
                }
 
1784
 
 
1785
                internal override void Write(MetadataWriter mw)
 
1786
                {
 
1787
                        for (int i = 0; i < rowCount; i++)
 
1788
                        {
 
1789
                                mw.Write(records[i].Semantics);
 
1790
                                mw.WriteMethodDef(records[i].Method);
 
1791
                                mw.WriteHasSemantics(records[i].Association);
 
1792
                        }
 
1793
                }
 
1794
 
 
1795
                protected override int GetRowSize(RowSizeCalc rsc)
 
1796
                {
 
1797
                        return rsc
 
1798
                                .AddFixed(2)
 
1799
                                .WriteMethodDef()
 
1800
                                .WriteHasSemantics()
 
1801
                                .Value;
 
1802
                }
 
1803
 
 
1804
                internal void Fixup(ModuleBuilder moduleBuilder)
 
1805
                {
 
1806
                        for (int i = 0; i < rowCount; i++)
 
1807
                        {
 
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)
 
1812
                                {
 
1813
                                        case EventTable.Index:
 
1814
                                                token = (token & 0xFFFFFF) << 1 | 0;
 
1815
                                                break;
 
1816
                                        case PropertyTable.Index:
 
1817
                                                token = (token & 0xFFFFFF) << 1 | 1;
 
1818
                                                break;
 
1819
                                        default:
 
1820
                                                throw new InvalidOperationException();
 
1821
                                }
 
1822
                                records[i].Association = token;
 
1823
                        }
 
1824
                        Sort();
 
1825
                }
 
1826
 
 
1827
                internal MethodInfo GetMethod(Module module, int token, bool nonPublic, short semantics)
 
1828
                {
 
1829
                        foreach (int i in Filter(token))
 
1830
                        {
 
1831
                                if ((records[i].Semantics & semantics) != 0)
 
1832
                                {
 
1833
                                        MethodBase method = module.ResolveMethod((MethodDefTable.Index << 24) + records[i].Method);
 
1834
                                        if (nonPublic || method.IsPublic)
 
1835
                                        {
 
1836
                                                return (MethodInfo)method;
 
1837
                                        }
 
1838
                                }
 
1839
                        }
 
1840
                        return null;
 
1841
                }
 
1842
 
 
1843
                internal MethodInfo[] GetMethods(Module module, int token, bool nonPublic, short semantics)
 
1844
                {
 
1845
                        List<MethodInfo> methods = new List<MethodInfo>();
 
1846
                        foreach (int i in Filter(token))
 
1847
                        {
 
1848
                                if ((records[i].Semantics & semantics) != 0)
 
1849
                                {
 
1850
                                        MethodInfo method = (MethodInfo)module.ResolveMethod((MethodDefTable.Index << 24) + records[i].Method);
 
1851
                                        if (nonPublic || method.IsPublic)
 
1852
                                        {
 
1853
                                                methods.Add(method);
 
1854
                                        }
 
1855
                                }
 
1856
                        }
 
1857
                        return methods.ToArray();
 
1858
                }
 
1859
 
 
1860
                internal void ComputeFlags(Module module, int token, out bool isPublic, out bool isNonPrivate, out bool isStatic)
 
1861
                {
 
1862
                        isPublic = false;
 
1863
                        isNonPrivate = false;
 
1864
                        isStatic = false;
 
1865
                        foreach (int i in Filter(token))
 
1866
                        {
 
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;
 
1871
                        }
 
1872
                }
 
1873
        }
 
1874
 
 
1875
        sealed class MethodImplTable : SortedTable<MethodImplTable.Record>
 
1876
        {
 
1877
                internal const int Index = 0x19;
 
1878
 
 
1879
                internal struct Record : IRecord
 
1880
                {
 
1881
                        internal int Class;
 
1882
                        internal int MethodBody;
 
1883
                        internal int MethodDeclaration;
 
1884
 
 
1885
                        int IRecord.SortKey
 
1886
                        {
 
1887
                                get { return Class; }
 
1888
                        }
 
1889
 
 
1890
                        int IRecord.FilterKey
 
1891
                        {
 
1892
                                get { return Class; }
 
1893
                        }
 
1894
                }
 
1895
 
 
1896
                internal override void Read(MetadataReader mr)
 
1897
                {
 
1898
                        for (int i = 0; i < records.Length; i++)
 
1899
                        {
 
1900
                                records[i].Class = mr.ReadTypeDef();
 
1901
                                records[i].MethodBody = mr.ReadMethodDefOrRef();
 
1902
                                records[i].MethodDeclaration = mr.ReadMethodDefOrRef();
 
1903
                        }
 
1904
                }
 
1905
 
 
1906
                internal override void Write(MetadataWriter mw)
 
1907
                {
 
1908
                        for (int i = 0; i < rowCount; i++)
 
1909
                        {
 
1910
                                mw.WriteTypeDef(records[i].Class);
 
1911
                                mw.WriteMethodDefOrRef(records[i].MethodBody);
 
1912
                                mw.WriteMethodDefOrRef(records[i].MethodDeclaration);
 
1913
                        }
 
1914
                }
 
1915
 
 
1916
                protected override int GetRowSize(RowSizeCalc rsc)
 
1917
                {
 
1918
                        return rsc
 
1919
                                .WriteTypeDef()
 
1920
                                .WriteMethodDefOrRef()
 
1921
                                .WriteMethodDefOrRef()
 
1922
                                .Value;
 
1923
                }
 
1924
 
 
1925
                internal void Fixup(ModuleBuilder moduleBuilder)
 
1926
                {
 
1927
                        for (int i = 0; i < rowCount; i++)
 
1928
                        {
 
1929
                                moduleBuilder.FixupPseudoToken(ref records[i].MethodBody);
 
1930
                                moduleBuilder.FixupPseudoToken(ref records[i].MethodDeclaration);
 
1931
                        }
 
1932
                        Sort();
 
1933
                }
 
1934
        }
 
1935
 
 
1936
        sealed class ModuleRefTable : Table<int>
 
1937
        {
 
1938
                internal const int Index = 0x1A;
 
1939
 
 
1940
                internal override void Read(MetadataReader mr)
 
1941
                {
 
1942
                        for (int i = 0; i < records.Length; i++)
 
1943
                        {
 
1944
                                records[i] = mr.ReadStringIndex();
 
1945
                        }
 
1946
                }
 
1947
 
 
1948
                internal override void Write(MetadataWriter mw)
 
1949
                {
 
1950
                        for (int i = 0; i < rowCount; i++)
 
1951
                        {
 
1952
                                mw.WriteStringIndex(records[i]);
 
1953
                        }
 
1954
                }
 
1955
 
 
1956
                protected override int GetRowSize(RowSizeCalc rsc)
 
1957
                {
 
1958
                        return rsc
 
1959
                                .WriteStringIndex()
 
1960
                                .Value;
 
1961
                }
 
1962
 
 
1963
                internal int FindOrAddRecord(int str)
 
1964
                {
 
1965
                        for (int i = 0; i < rowCount; i++)
 
1966
                        {
 
1967
                                if (records[i] == str)
 
1968
                                {
 
1969
                                        return i + 1;
 
1970
                                }
 
1971
                        }
 
1972
                        return AddRecord(str);
 
1973
                }
 
1974
        }
 
1975
 
 
1976
        sealed class TypeSpecTable : Table<int>
 
1977
        {
 
1978
                internal const int Index = 0x1B;
 
1979
 
 
1980
                internal override void Read(MetadataReader mr)
 
1981
                {
 
1982
                        for (int i = 0; i < records.Length; i++)
 
1983
                        {
 
1984
                                records[i] = mr.ReadBlobIndex();
 
1985
                        }
 
1986
                }
 
1987
 
 
1988
                internal override void Write(MetadataWriter mw)
 
1989
                {
 
1990
                        for (int i = 0; i < rowCount; i++)
 
1991
                        {
 
1992
                                mw.WriteBlobIndex(records[i]);
 
1993
                        }
 
1994
                }
 
1995
 
 
1996
                protected override int GetRowSize(Table.RowSizeCalc rsc)
 
1997
                {
 
1998
                        return rsc.WriteBlobIndex().Value;
 
1999
                }
 
2000
        }
 
2001
 
 
2002
        sealed class ImplMapTable : SortedTable<ImplMapTable.Record>
 
2003
        {
 
2004
                internal const int Index = 0x1C;
 
2005
 
 
2006
                internal struct Record : IRecord
 
2007
                {
 
2008
                        internal short MappingFlags;
 
2009
                        internal int MemberForwarded;
 
2010
                        internal int ImportName;
 
2011
                        internal int ImportScope;
 
2012
 
 
2013
                        int IRecord.SortKey
 
2014
                        {
 
2015
                                get { return MemberForwarded; }
 
2016
                        }
 
2017
 
 
2018
                        int IRecord.FilterKey
 
2019
                        {
 
2020
                                get { return MemberForwarded; }
 
2021
                        }
 
2022
                }
 
2023
 
 
2024
                internal override void Read(MetadataReader mr)
 
2025
                {
 
2026
                        for (int i = 0; i < records.Length; i++)
 
2027
                        {
 
2028
                                records[i].MappingFlags = mr.ReadInt16();
 
2029
                                records[i].MemberForwarded = mr.ReadMemberForwarded();
 
2030
                                records[i].ImportName = mr.ReadStringIndex();
 
2031
                                records[i].ImportScope = mr.ReadModuleRef();
 
2032
                        }
 
2033
                }
 
2034
 
 
2035
                internal override void Write(MetadataWriter mw)
 
2036
                {
 
2037
                        for (int i = 0; i < rowCount; i++)
 
2038
                        {
 
2039
                                mw.Write(records[i].MappingFlags);
 
2040
                                mw.WriteMemberForwarded(records[i].MemberForwarded);
 
2041
                                mw.WriteStringIndex(records[i].ImportName);
 
2042
                                mw.WriteModuleRef(records[i].ImportScope);
 
2043
                        }
 
2044
                }
 
2045
 
 
2046
                protected override int GetRowSize(RowSizeCalc rsc)
 
2047
                {
 
2048
                        return rsc
 
2049
                                .AddFixed(2)
 
2050
                                .WriteMemberForwarded()
 
2051
                                .WriteStringIndex()
 
2052
                                .WriteModuleRef()
 
2053
                                .Value;
 
2054
                }
 
2055
 
 
2056
                internal void Fixup(ModuleBuilder moduleBuilder)
 
2057
                {
 
2058
                        for (int i = 0; i < rowCount; i++)
 
2059
                        {
 
2060
                                moduleBuilder.FixupPseudoToken(ref records[i].MemberForwarded);
 
2061
                        }
 
2062
                        Sort();
 
2063
                }
 
2064
        }
 
2065
 
 
2066
        sealed class FieldRVATable : SortedTable<FieldRVATable.Record>
 
2067
        {
 
2068
                internal const int Index = 0x1D;
 
2069
 
 
2070
                internal struct Record : IRecord
 
2071
                {
 
2072
                        internal int RVA;               // we set the high bit to signify that the RVA is in the CIL stream (instead of .sdata)
 
2073
                        internal int Field;
 
2074
 
 
2075
                        int IRecord.SortKey
 
2076
                        {
 
2077
                                get { return Field; }
 
2078
                        }
 
2079
 
 
2080
                        int IRecord.FilterKey
 
2081
                        {
 
2082
                                get { return Field; }
 
2083
                        }
 
2084
                }
 
2085
 
 
2086
                internal override void Read(MetadataReader mr)
 
2087
                {
 
2088
                        for (int i = 0; i < records.Length; i++)
 
2089
                        {
 
2090
                                records[i].RVA = mr.ReadInt32();
 
2091
                                records[i].Field = mr.ReadField();
 
2092
                        }
 
2093
                }
 
2094
 
 
2095
                internal override void Write(MetadataWriter mw)
 
2096
                {
 
2097
                        for (int i = 0; i < rowCount; i++)
 
2098
                        {
 
2099
                                mw.Write(records[i].RVA);
 
2100
                                mw.WriteField(records[i].Field);
 
2101
                        }
 
2102
                }
 
2103
 
 
2104
                protected override int GetRowSize(RowSizeCalc rsc)
 
2105
                {
 
2106
                        return rsc
 
2107
                                .AddFixed(4)
 
2108
                                .WriteField()
 
2109
                                .Value;
 
2110
                }
 
2111
 
 
2112
                internal void Fixup(ModuleBuilder moduleBuilder, int sdataRVA, int cilRVA)
 
2113
                {
 
2114
                        for (int i = 0; i < rowCount; i++)
 
2115
                        {
 
2116
                                if (records[i].RVA < 0)
 
2117
                                {
 
2118
                                        records[i].RVA = (records[i].RVA & 0x7fffffff) + cilRVA;
 
2119
                                }
 
2120
                                else
 
2121
                                {
 
2122
                                        records[i].RVA += sdataRVA;
 
2123
                                }
 
2124
                                moduleBuilder.FixupPseudoToken(ref records[i].Field);
 
2125
                        }
 
2126
                        Sort();
 
2127
                }
 
2128
        }
 
2129
 
 
2130
        sealed class AssemblyTable : Table<AssemblyTable.Record>
 
2131
        {
 
2132
                internal const int Index = 0x20;
 
2133
 
 
2134
                internal struct Record
 
2135
                {
 
2136
                        internal int HashAlgId;
 
2137
                        internal ushort MajorVersion;
 
2138
                        internal ushort MinorVersion;
 
2139
                        internal ushort BuildNumber;
 
2140
                        internal ushort RevisionNumber;
 
2141
                        internal int Flags;
 
2142
                        internal int PublicKey;
 
2143
                        internal int Name;
 
2144
                        internal int Culture;
 
2145
                }
 
2146
 
 
2147
                internal override void Read(MetadataReader mr)
 
2148
                {
 
2149
                        for (int i = 0; i < records.Length; i++)
 
2150
                        {
 
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();
 
2160
                        }
 
2161
                }
 
2162
 
 
2163
                internal override void Write(MetadataWriter mw)
 
2164
                {
 
2165
                        for (int i = 0; i < rowCount; i++)
 
2166
                        {
 
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);
 
2176
                        }
 
2177
                }
 
2178
 
 
2179
                protected override int GetRowSize(RowSizeCalc rsc)
 
2180
                {
 
2181
                        return rsc
 
2182
                                .AddFixed(16)
 
2183
                                .WriteBlobIndex()
 
2184
                                .WriteStringIndex()
 
2185
                                .WriteStringIndex()
 
2186
                                .Value;
 
2187
                }
 
2188
        }
 
2189
 
 
2190
        sealed class AssemblyRefTable : Table<AssemblyRefTable.Record>
 
2191
        {
 
2192
                internal const int Index = 0x23;
 
2193
 
 
2194
                internal struct Record
 
2195
                {
 
2196
                        internal ushort MajorVersion;
 
2197
                        internal ushort MinorVersion;
 
2198
                        internal ushort BuildNumber;
 
2199
                        internal ushort RevisionNumber;
 
2200
                        internal int Flags;
 
2201
                        internal int PublicKeyOrToken;
 
2202
                        internal int Name;
 
2203
                        internal int Culture;
 
2204
                        internal int HashValue;
 
2205
                }
 
2206
 
 
2207
                internal int FindOrAddRecord(Record rec)
 
2208
                {
 
2209
                        for (int i = 0; i < rowCount; i++)
 
2210
                        {
 
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
 
2220
                                        )
 
2221
                                {
 
2222
                                        return i + 1;
 
2223
                                }
 
2224
                        }
 
2225
                        return AddRecord(rec);
 
2226
                }
 
2227
 
 
2228
                internal override void Read(MetadataReader mr)
 
2229
                {
 
2230
                        for (int i = 0; i < records.Length; i++)
 
2231
                        {
 
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();
 
2241
                        }
 
2242
                }
 
2243
 
 
2244
                internal override void Write(MetadataWriter mw)
 
2245
                {
 
2246
                        for (int i = 0; i < rowCount; i++)
 
2247
                        {
 
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);
 
2257
                        }
 
2258
                }
 
2259
 
 
2260
                protected override int GetRowSize(RowSizeCalc rsc)
 
2261
                {
 
2262
                        return rsc
 
2263
                                .AddFixed(12)
 
2264
                                .WriteBlobIndex()
 
2265
                                .WriteStringIndex()
 
2266
                                .WriteStringIndex()
 
2267
                                .WriteBlobIndex()
 
2268
                                .Value;
 
2269
                }
 
2270
        }
 
2271
 
 
2272
        sealed class FileTable : Table<FileTable.Record>
 
2273
        {
 
2274
                internal const int Index = 0x26;
 
2275
 
 
2276
                internal struct Record
 
2277
                {
 
2278
                        internal int Flags;
 
2279
                        internal int Name;
 
2280
                        internal int HashValue;
 
2281
                }
 
2282
 
 
2283
                internal override void Read(MetadataReader mr)
 
2284
                {
 
2285
                        for (int i = 0; i < records.Length; i++)
 
2286
                        {
 
2287
                                records[i].Flags = mr.ReadInt32();
 
2288
                                records[i].Name = mr.ReadStringIndex();
 
2289
                                records[i].HashValue = mr.ReadBlobIndex();
 
2290
                        }
 
2291
                }
 
2292
 
 
2293
                internal override void Write(MetadataWriter mw)
 
2294
                {
 
2295
                        for (int i = 0; i < rowCount; i++)
 
2296
                        {
 
2297
                                mw.Write(records[i].Flags);
 
2298
                                mw.WriteStringIndex(records[i].Name);
 
2299
                                mw.WriteBlobIndex(records[i].HashValue);
 
2300
                        }
 
2301
                }
 
2302
 
 
2303
                protected override int GetRowSize(RowSizeCalc rsc)
 
2304
                {
 
2305
                        return rsc
 
2306
                                .AddFixed(4)
 
2307
                                .WriteStringIndex()
 
2308
                                .WriteBlobIndex()
 
2309
                                .Value;
 
2310
                }
 
2311
        }
 
2312
 
 
2313
        sealed class ExportedTypeTable : Table<ExportedTypeTable.Record>
 
2314
        {
 
2315
                internal const int Index = 0x27;
 
2316
 
 
2317
                internal struct Record
 
2318
                {
 
2319
                        internal int Flags;
 
2320
                        internal int TypeDefId;
 
2321
                        internal int TypeName;
 
2322
                        internal int TypeNamespace;
 
2323
                        internal int Implementation;
 
2324
                }
 
2325
 
 
2326
                internal override void Read(MetadataReader mr)
 
2327
                {
 
2328
                        for (int i = 0; i < records.Length; i++)
 
2329
                        {
 
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();
 
2335
                        }
 
2336
                }
 
2337
 
 
2338
                internal override void Write(MetadataWriter mw)
 
2339
                {
 
2340
                        for (int i = 0; i < rowCount; i++)
 
2341
                        {
 
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);
 
2347
                        }
 
2348
                }
 
2349
 
 
2350
                protected override int GetRowSize(RowSizeCalc rsc)
 
2351
                {
 
2352
                        return rsc
 
2353
                                .AddFixed(8)
 
2354
                                .WriteStringIndex()
 
2355
                                .WriteStringIndex()
 
2356
                                .WriteImplementation()
 
2357
                                .Value;
 
2358
                }
 
2359
 
 
2360
                internal int FindOrAddRecord(Record rec)
 
2361
                {
 
2362
                        for (int i = 0; i < rowCount; i++)
 
2363
                        {
 
2364
                                if (records[i].Implementation == rec.Implementation
 
2365
                                        && records[i].TypeName == rec.TypeName
 
2366
                                        && records[i].TypeNamespace == rec.TypeNamespace)
 
2367
                                {
 
2368
                                        return i + 1;
 
2369
                                }
 
2370
                        }
 
2371
                        return AddRecord(rec);
 
2372
                }
 
2373
 
 
2374
                internal void Fixup(ModuleBuilder moduleBuilder)
 
2375
                {
 
2376
                        for (int i = 0; i < rowCount; i++)
 
2377
                        {
 
2378
                                moduleBuilder.FixupPseudoToken(ref records[i].Implementation);
 
2379
                        }
 
2380
                }
 
2381
        }
 
2382
 
 
2383
        sealed class ManifestResourceTable : Table<ManifestResourceTable.Record>
 
2384
        {
 
2385
                internal const int Index = 0x28;
 
2386
 
 
2387
                internal struct Record
 
2388
                {
 
2389
                        internal int Offset;
 
2390
                        internal int Flags;
 
2391
                        internal int Name;
 
2392
                        internal int Implementation;
 
2393
                }
 
2394
 
 
2395
                internal override void Read(MetadataReader mr)
 
2396
                {
 
2397
                        for (int i = 0; i < records.Length; i++)
 
2398
                        {
 
2399
                                records[i].Offset = mr.ReadInt32();
 
2400
                                records[i].Flags = mr.ReadInt32();
 
2401
                                records[i].Name = mr.ReadStringIndex();
 
2402
                                records[i].Implementation = mr.ReadImplementation();
 
2403
                        }
 
2404
                }
 
2405
 
 
2406
                internal override void Write(MetadataWriter mw)
 
2407
                {
 
2408
                        for (int i = 0; i < rowCount; i++)
 
2409
                        {
 
2410
                                mw.Write(records[i].Offset);
 
2411
                                mw.Write(records[i].Flags);
 
2412
                                mw.WriteStringIndex(records[i].Name);
 
2413
                                mw.WriteImplementation(records[i].Implementation);
 
2414
                        }
 
2415
                }
 
2416
 
 
2417
                protected override int GetRowSize(RowSizeCalc rsc)
 
2418
                {
 
2419
                        return rsc
 
2420
                                .AddFixed(8)
 
2421
                                .WriteStringIndex()
 
2422
                                .WriteImplementation()
 
2423
                                .Value;
 
2424
                }
 
2425
 
 
2426
                internal void Fixup(ModuleBuilder moduleBuilder)
 
2427
                {
 
2428
                        for (int i = 0; i < rowCount; i++)
 
2429
                        {
 
2430
                                moduleBuilder.FixupPseudoToken(ref records[i].Implementation);
 
2431
                        }
 
2432
                }
 
2433
        }
 
2434
 
 
2435
        sealed class NestedClassTable : SortedTable<NestedClassTable.Record>
 
2436
        {
 
2437
                internal const int Index = 0x29;
 
2438
 
 
2439
                internal struct Record : IRecord
 
2440
                {
 
2441
                        internal int NestedClass;
 
2442
                        internal int EnclosingClass;
 
2443
 
 
2444
                        int IRecord.SortKey
 
2445
                        {
 
2446
                                get { return NestedClass; }
 
2447
                        }
 
2448
 
 
2449
                        int IRecord.FilterKey
 
2450
                        {
 
2451
                                get { return NestedClass; }
 
2452
                        }
 
2453
                }
 
2454
 
 
2455
                internal override void Read(MetadataReader mr)
 
2456
                {
 
2457
                        for (int i = 0; i < records.Length; i++)
 
2458
                        {
 
2459
                                records[i].NestedClass = mr.ReadTypeDef();
 
2460
                                records[i].EnclosingClass = mr.ReadTypeDef();
 
2461
                        }
 
2462
                }
 
2463
 
 
2464
                internal override void Write(MetadataWriter mw)
 
2465
                {
 
2466
                        for (int i = 0; i < rowCount; i++)
 
2467
                        {
 
2468
                                mw.WriteTypeDef(records[i].NestedClass);
 
2469
                                mw.WriteTypeDef(records[i].EnclosingClass);
 
2470
                        }
 
2471
                }
 
2472
 
 
2473
                protected override int GetRowSize(RowSizeCalc rsc)
 
2474
                {
 
2475
                        return rsc
 
2476
                                .WriteTypeDef()
 
2477
                                .WriteTypeDef()
 
2478
                                .Value;
 
2479
                }
 
2480
 
 
2481
                internal List<int> GetNestedClasses(int enclosingClass)
 
2482
                {
 
2483
                        List<int> nestedClasses = new List<int>();
 
2484
                        for (int i = 0; i < rowCount; i++)
 
2485
                        {
 
2486
                                if (records[i].EnclosingClass == enclosingClass)
 
2487
                                {
 
2488
                                        nestedClasses.Add(records[i].NestedClass);
 
2489
                                }
 
2490
                        }
 
2491
                        return nestedClasses;
 
2492
                }
 
2493
        }
 
2494
 
 
2495
        sealed class GenericParamTable : SortedTable<GenericParamTable.Record>, IComparer<GenericParamTable.Record>
 
2496
        {
 
2497
                internal const int Index = 0x2A;
 
2498
 
 
2499
                internal struct Record : IRecord
 
2500
                {
 
2501
                        internal short Number;
 
2502
                        internal short Flags;
 
2503
                        internal int Owner;
 
2504
                        internal int Name;
 
2505
                        // not part of the table, we use it to be able to fixup the GenericParamConstraint table
 
2506
                        internal int unsortedIndex;
 
2507
 
 
2508
                        int IRecord.SortKey
 
2509
                        {
 
2510
                                get { return Owner; }
 
2511
                        }
 
2512
 
 
2513
                        int IRecord.FilterKey
 
2514
                        {
 
2515
                                get { return Owner; }
 
2516
                        }
 
2517
                }
 
2518
 
 
2519
                internal override void Read(MetadataReader mr)
 
2520
                {
 
2521
                        for (int i = 0; i < records.Length; i++)
 
2522
                        {
 
2523
                                records[i].Number = mr.ReadInt16();
 
2524
                                records[i].Flags = mr.ReadInt16();
 
2525
                                records[i].Owner = mr.ReadTypeOrMethodDef();
 
2526
                                records[i].Name = mr.ReadStringIndex();
 
2527
                        }
 
2528
                }
 
2529
 
 
2530
                internal override void Write(MetadataWriter mw)
 
2531
                {
 
2532
                        for (int i = 0; i < rowCount; i++)
 
2533
                        {
 
2534
                                mw.Write(records[i].Number);
 
2535
                                mw.Write(records[i].Flags);
 
2536
                                mw.WriteTypeOrMethodDef(records[i].Owner);
 
2537
                                mw.WriteStringIndex(records[i].Name);
 
2538
                        }
 
2539
                }
 
2540
 
 
2541
                protected override int GetRowSize(RowSizeCalc rsc)
 
2542
                {
 
2543
                        return rsc
 
2544
                                .AddFixed(4)
 
2545
                                .WriteTypeOrMethodDef()
 
2546
                                .WriteStringIndex()
 
2547
                                .Value;
 
2548
                }
 
2549
 
 
2550
                internal void Fixup(ModuleBuilder moduleBuilder)
 
2551
                {
 
2552
                        for (int i = 0; i < rowCount; i++)
 
2553
                        {
 
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)
 
2558
                                {
 
2559
                                        case TypeDefTable.Index:
 
2560
                                                records[i].Owner = (token & 0xFFFFFF) << 1 | 0;
 
2561
                                                break;
 
2562
                                        case MethodDefTable.Index:
 
2563
                                                records[i].Owner = (token & 0xFFFFFF) << 1 | 1;
 
2564
                                                break;
 
2565
                                        default:
 
2566
                                                throw new InvalidOperationException();
 
2567
                                }
 
2568
                                records[i].unsortedIndex = i;
 
2569
                        }
 
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);
 
2572
                }
 
2573
 
 
2574
                int IComparer<Record>.Compare(Record x, Record y)
 
2575
                {
 
2576
                        if (x.Owner == y.Owner)
 
2577
                        {
 
2578
                                return x.Number == y.Number ? 0 : (x.Number > y.Number ? 1 : -1);
 
2579
                        }
 
2580
                        return x.Owner > y.Owner ? 1 : -1;
 
2581
                }
 
2582
 
 
2583
                internal void PatchAttribute(int token, GenericParameterAttributes genericParameterAttributes)
 
2584
                {
 
2585
                        records[(token & 0xFFFFFF) - 1].Flags = (short)genericParameterAttributes;
 
2586
                }
 
2587
 
 
2588
                internal int[] GetIndexFixup()
 
2589
                {
 
2590
                        int[] array = new int[rowCount];
 
2591
                        for (int i = 0; i < rowCount; i++)
 
2592
                        {
 
2593
                                array[records[i].unsortedIndex] = i;
 
2594
                        }
 
2595
                        return array;
 
2596
                }
 
2597
 
 
2598
                internal int FindFirstByOwner(int token)
 
2599
                {
 
2600
                        foreach (int i in Filter(token))
 
2601
                        {
 
2602
                                return i;
 
2603
                        }
 
2604
                        return -1;
 
2605
                }
 
2606
        }
 
2607
 
 
2608
        sealed class MethodSpecTable : Table<MethodSpecTable.Record>
 
2609
        {
 
2610
                internal const int Index = 0x2B;
 
2611
 
 
2612
                internal struct Record
 
2613
                {
 
2614
                        internal int Method;
 
2615
                        internal int Instantiation;
 
2616
                }
 
2617
 
 
2618
                internal override void Read(MetadataReader mr)
 
2619
                {
 
2620
                        for (int i = 0; i < records.Length; i++)
 
2621
                        {
 
2622
                                records[i].Method = mr.ReadMethodDefOrRef();
 
2623
                                records[i].Instantiation = mr.ReadBlobIndex();
 
2624
                        }
 
2625
                }
 
2626
 
 
2627
                internal override void Write(MetadataWriter mw)
 
2628
                {
 
2629
                        for (int i = 0; i < rowCount; i++)
 
2630
                        {
 
2631
                                mw.WriteMethodDefOrRef(records[i].Method);
 
2632
                                mw.WriteBlobIndex(records[i].Instantiation);
 
2633
                        }
 
2634
                }
 
2635
 
 
2636
                protected override int GetRowSize(RowSizeCalc rsc)
 
2637
                {
 
2638
                        return rsc
 
2639
                                .WriteMethodDefOrRef()
 
2640
                                .WriteBlobIndex()
 
2641
                                .Value;
 
2642
                }
 
2643
 
 
2644
                internal int FindOrAddRecord(Record record)
 
2645
                {
 
2646
                        for (int i = 0; i < rowCount; i++)
 
2647
                        {
 
2648
                                if (records[i].Method == record.Method
 
2649
                                        && records[i].Instantiation == record.Instantiation)
 
2650
                                {
 
2651
                                        return i + 1;
 
2652
                                }
 
2653
                        }
 
2654
                        return AddRecord(record);
 
2655
                }
 
2656
 
 
2657
                internal void Fixup(ModuleBuilder moduleBuilder)
 
2658
                {
 
2659
                        for (int i = 0; i < rowCount; i++)
 
2660
                        {
 
2661
                                moduleBuilder.FixupPseudoToken(ref records[i].Method);
 
2662
                        }
 
2663
                }
 
2664
        }
 
2665
 
 
2666
        sealed class GenericParamConstraintTable : SortedTable<GenericParamConstraintTable.Record>
 
2667
        {
 
2668
                internal const int Index = 0x2C;
 
2669
 
 
2670
                internal struct Record : IRecord
 
2671
                {
 
2672
                        internal int Owner;
 
2673
                        internal int Constraint;
 
2674
 
 
2675
                        int IRecord.SortKey
 
2676
                        {
 
2677
                                get { return Owner; }
 
2678
                        }
 
2679
 
 
2680
                        int IRecord.FilterKey
 
2681
                        {
 
2682
                                get { return Owner; }
 
2683
                        }
 
2684
                }
 
2685
 
 
2686
                internal override void Read(MetadataReader mr)
 
2687
                {
 
2688
                        for (int i = 0; i < records.Length; i++)
 
2689
                        {
 
2690
                                records[i].Owner = mr.ReadGenericParam();
 
2691
                                records[i].Constraint = mr.ReadTypeDefOrRef();
 
2692
                        }
 
2693
                }
 
2694
 
 
2695
                internal override void Write(MetadataWriter mw)
 
2696
                {
 
2697
                        for (int i = 0; i < rowCount; i++)
 
2698
                        {
 
2699
                                mw.WriteGenericParam(records[i].Owner);
 
2700
                                mw.WriteTypeDefOrRef(records[i].Constraint);
 
2701
                        }
 
2702
                }
 
2703
 
 
2704
                protected override int GetRowSize(RowSizeCalc rsc)
 
2705
                {
 
2706
                        return rsc
 
2707
                                .WriteGenericParam()
 
2708
                                .WriteTypeDefOrRef()
 
2709
                                .Value;
 
2710
                }
 
2711
 
 
2712
                internal void Fixup(ModuleBuilder moduleBuilder)
 
2713
                {
 
2714
                        int[] fixups = moduleBuilder.GenericParam.GetIndexFixup();
 
2715
                        for (int i = 0; i < rowCount; i++)
 
2716
                        {
 
2717
                                records[i].Owner = fixups[records[i].Owner - 1] + 1;
 
2718
                        }
 
2719
                        Sort();
 
2720
                }
 
2721
        }
 
2722
}