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

« back to all changes in this revision

Viewing changes to external/mono-addins/Mono.Addins.CecilReflector/Mono.Cecil/Mono.Cecil.Cil/CodeReader.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
// CodeReader.cs
 
3
//
 
4
// Author:
 
5
//   Jb Evain (jbevain@gmail.com)
 
6
//
 
7
// Copyright (c) 2008 - 2010 Jb Evain
 
8
//
 
9
// Permission is hereby granted, free of charge, to any person obtaining
 
10
// a copy of this software and associated documentation files (the
 
11
// "Software"), to deal in the Software without restriction, including
 
12
// without limitation the rights to use, copy, modify, merge, publish,
 
13
// distribute, sublicense, and/or sell copies of the Software, and to
 
14
// permit persons to whom the Software is furnished to do so, subject to
 
15
// the following conditions:
 
16
//
 
17
// The above copyright notice and this permission notice shall be
 
18
// included in all copies or substantial portions of the Software.
 
19
//
 
20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
21
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
22
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
23
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 
24
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 
25
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 
26
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
27
//
 
28
 
 
29
using System;
 
30
 
 
31
using Mono.Cecil.PE;
 
32
using Mono.Collections.Generic;
 
33
 
 
34
using RVA = System.UInt32;
 
35
 
 
36
namespace Mono.Cecil.Cil {
 
37
 
 
38
        sealed class CodeReader : ByteBuffer {
 
39
 
 
40
                readonly internal MetadataReader reader;
 
41
 
 
42
                int start;
 
43
                Section code_section;
 
44
 
 
45
                MethodDefinition method;
 
46
                MethodBody body;
 
47
 
 
48
                int Offset {
 
49
                        get { return base.position - start; }
 
50
                }
 
51
 
 
52
                CodeReader (Section section, MetadataReader reader)
 
53
                        : base (section.Data)
 
54
                {
 
55
                        this.code_section = section;
 
56
                        this.reader = reader;
 
57
                }
 
58
 
 
59
                public static CodeReader CreateCodeReader (MetadataReader metadata)
 
60
                {
 
61
                        return new CodeReader (metadata.image.MetadataSection, metadata);
 
62
                }
 
63
 
 
64
                public MethodBody ReadMethodBody (MethodDefinition method)
 
65
                {
 
66
                        this.method = method;
 
67
                        this.body = new MethodBody (method);
 
68
 
 
69
                        reader.context = method;
 
70
 
 
71
                        ReadMethodBody ();
 
72
 
 
73
                        return this.body;
 
74
                }
 
75
 
 
76
                public void MoveTo (int rva)
 
77
                {
 
78
                        if (!IsInSection (rva)) {
 
79
                                code_section = reader.image.GetSectionAtVirtualAddress ((uint) rva);
 
80
                                Reset (code_section.Data);
 
81
                        }
 
82
 
 
83
                        base.position = rva - (int) code_section.VirtualAddress;
 
84
                }
 
85
 
 
86
                bool IsInSection (int rva)
 
87
                {
 
88
                        return code_section.VirtualAddress <= rva && rva < code_section.VirtualAddress + code_section.SizeOfRawData;
 
89
                }
 
90
 
 
91
                void ReadMethodBody ()
 
92
                {
 
93
                        MoveTo (method.RVA);
 
94
 
 
95
                        var flags = ReadByte ();
 
96
                        switch (flags & 0x3) {
 
97
                        case 0x2: // tiny
 
98
                                body.code_size = flags >> 2;
 
99
                                body.MaxStackSize = 8;
 
100
                                ReadCode ();
 
101
                                break;
 
102
                        case 0x3: // fat
 
103
                                base.position--;
 
104
                                ReadFatMethod ();
 
105
                                break;
 
106
                        default:
 
107
                                throw new InvalidOperationException ();
 
108
                        }
 
109
 
 
110
                        var symbol_reader = reader.module.SymbolReader;
 
111
 
 
112
                        if (symbol_reader != null) {
 
113
                                var instructions = body.Instructions;
 
114
                                symbol_reader.Read (body, offset => GetInstruction (instructions, offset));
 
115
                        }
 
116
                }
 
117
 
 
118
                void ReadFatMethod ()
 
119
                {
 
120
                        var flags = ReadUInt16 ();
 
121
                        body.max_stack_size = ReadUInt16 ();
 
122
                        body.code_size = (int) ReadUInt32 ();
 
123
                        body.local_var_token = new MetadataToken (ReadUInt32 ());
 
124
                        body.init_locals = (flags & 0x10) != 0;
 
125
 
 
126
                        if (body.local_var_token.RID != 0)
 
127
                                body.variables = ReadVariables (body.local_var_token);
 
128
 
 
129
                        ReadCode ();
 
130
 
 
131
                        if ((flags & 0x8) != 0)
 
132
                                ReadSection ();
 
133
                }
 
134
 
 
135
                public VariableDefinitionCollection ReadVariables (MetadataToken local_var_token)
 
136
                {
 
137
                        var position = reader.position;
 
138
                        var variables = reader.ReadVariables (local_var_token);
 
139
                        reader.position = position;
 
140
 
 
141
                        return variables;
 
142
                }
 
143
 
 
144
                void ReadCode ()
 
145
                {
 
146
                        start = position;
 
147
                        var code_size = body.code_size;
 
148
 
 
149
                        if (code_size < 0 || buffer.Length <= (uint) (code_size + position))
 
150
                                code_size = 0;
 
151
 
 
152
                        var end = start + code_size;
 
153
                        var instructions = body.instructions = new InstructionCollection (code_size / 3);
 
154
 
 
155
                        while (position < end) {
 
156
                                var offset = base.position - start;
 
157
                                var opcode = ReadOpCode ();
 
158
                                var current = new Instruction (offset, opcode);
 
159
 
 
160
                                if (opcode.OperandType != OperandType.InlineNone)
 
161
                                        current.operand = ReadOperand (current);
 
162
 
 
163
                                instructions.Add (current);
 
164
                        }
 
165
 
 
166
                        ResolveBranches (instructions);
 
167
                }
 
168
 
 
169
                OpCode ReadOpCode ()
 
170
                {
 
171
                        var il_opcode = ReadByte ();
 
172
                        return il_opcode != 0xfe
 
173
                                ? OpCodes.OneByteOpCode [il_opcode]
 
174
                                : OpCodes.TwoBytesOpCode [ReadByte ()];
 
175
                }
 
176
 
 
177
                object ReadOperand (Instruction instruction)
 
178
                {
 
179
                        switch (instruction.opcode.OperandType) {
 
180
                        case OperandType.InlineSwitch:
 
181
                                var length = ReadInt32 ();
 
182
                                var base_offset = Offset + (4 * length);
 
183
                                var branches = new int [length];
 
184
                                for (int i = 0; i < length; i++)
 
185
                                        branches [i] = base_offset + ReadInt32 ();
 
186
                                return branches;
 
187
                        case OperandType.ShortInlineBrTarget:
 
188
                                return ReadSByte () + Offset;
 
189
                        case OperandType.InlineBrTarget:
 
190
                                return ReadInt32 () + Offset;
 
191
                        case OperandType.ShortInlineI:
 
192
                                if (instruction.opcode == OpCodes.Ldc_I4_S)
 
193
                                        return ReadSByte ();
 
194
 
 
195
                                return ReadByte ();
 
196
                        case OperandType.InlineI:
 
197
                                return ReadInt32 ();
 
198
                        case OperandType.ShortInlineR:
 
199
                                return ReadSingle ();
 
200
                        case OperandType.InlineR:
 
201
                                return ReadDouble ();
 
202
                        case OperandType.InlineI8:
 
203
                                return ReadInt64 ();
 
204
                        case OperandType.ShortInlineVar:
 
205
                                return GetVariable (ReadByte ());
 
206
                        case OperandType.InlineVar:
 
207
                                return GetVariable (ReadUInt16 ());
 
208
                        case OperandType.ShortInlineArg:
 
209
                                return GetParameter (ReadByte ());
 
210
                        case OperandType.InlineArg:
 
211
                                return GetParameter (ReadUInt16 ());
 
212
                        case OperandType.InlineSig:
 
213
                                return GetCallSite (ReadToken ());
 
214
                        case OperandType.InlineString:
 
215
                                return GetString (ReadToken ());
 
216
                        case OperandType.InlineTok:
 
217
                        case OperandType.InlineType:
 
218
                        case OperandType.InlineMethod:
 
219
                        case OperandType.InlineField:
 
220
                                return reader.LookupToken (ReadToken ());
 
221
                        default:
 
222
                                throw new NotSupportedException ();
 
223
                        }
 
224
                }
 
225
 
 
226
                public string GetString (MetadataToken token)
 
227
                {
 
228
                        return reader.image.UserStringHeap.Read (token.RID);
 
229
                }
 
230
 
 
231
                public ParameterDefinition GetParameter (int index)
 
232
                {
 
233
                        return body.GetParameter (index);
 
234
                }
 
235
 
 
236
                public VariableDefinition GetVariable (int index)
 
237
                {
 
238
                        return body.GetVariable (index);
 
239
                }
 
240
 
 
241
                public CallSite GetCallSite (MetadataToken token)
 
242
                {
 
243
                        return reader.ReadCallSite (token);
 
244
                }
 
245
 
 
246
                void ResolveBranches (Collection<Instruction> instructions)
 
247
                {
 
248
                        var items = instructions.items;
 
249
                        var size = instructions.size;
 
250
 
 
251
                        for (int i = 0; i < size; i++) {
 
252
                                var instruction = items [i];
 
253
                                switch (instruction.opcode.OperandType) {
 
254
                                case OperandType.ShortInlineBrTarget:
 
255
                                case OperandType.InlineBrTarget:
 
256
                                        instruction.operand = GetInstruction ((int) instruction.operand);
 
257
                                        break;
 
258
                                case OperandType.InlineSwitch:
 
259
                                        var offsets = (int []) instruction.operand;
 
260
                                        var branches = new Instruction [offsets.Length];
 
261
                                        for (int j = 0; j < offsets.Length; j++)
 
262
                                                branches [j] = GetInstruction (offsets [j]);
 
263
 
 
264
                                        instruction.operand = branches;
 
265
                                        break;
 
266
                                }
 
267
                        }
 
268
                }
 
269
 
 
270
                Instruction GetInstruction (int offset)
 
271
                {
 
272
                        return GetInstruction (body.Instructions, offset);
 
273
                }
 
274
 
 
275
                static Instruction GetInstruction (Collection<Instruction> instructions, int offset)
 
276
                {
 
277
                        var size = instructions.size;
 
278
                        var items = instructions.items;
 
279
                        if (offset < 0 || offset > items [size - 1].offset)
 
280
                                return null;
 
281
 
 
282
                        int min = 0;
 
283
                        int max = size - 1;
 
284
                        while (min <= max) {
 
285
                                int mid = min + ((max - min) / 2);
 
286
                                var instruction = items [mid];
 
287
                                var instruction_offset = instruction.offset;
 
288
 
 
289
                                if (offset == instruction_offset)
 
290
                                        return instruction;
 
291
 
 
292
                                if (offset < instruction_offset)
 
293
                                        max = mid - 1;
 
294
                                else
 
295
                                        min = mid + 1;
 
296
                        }
 
297
 
 
298
                        return null;
 
299
                }
 
300
 
 
301
                void ReadSection ()
 
302
                {
 
303
                        Align (4);
 
304
 
 
305
                        const byte fat_format = 0x40;
 
306
                        const byte more_sects = 0x80;
 
307
 
 
308
                        var flags = ReadByte ();
 
309
                        if ((flags & fat_format) == 0)
 
310
                                ReadSmallSection ();
 
311
                        else
 
312
                                ReadFatSection ();
 
313
 
 
314
                        if ((flags & more_sects) != 0)
 
315
                                ReadSection ();
 
316
                }
 
317
 
 
318
                void ReadSmallSection ()
 
319
                {
 
320
                        var count = ReadByte () / 12;
 
321
                        Advance (2);
 
322
 
 
323
                        ReadExceptionHandlers (
 
324
                                count,
 
325
                                () => (int) ReadUInt16 (),
 
326
                                () => (int) ReadByte ());
 
327
                }
 
328
 
 
329
                void ReadFatSection ()
 
330
                {
 
331
                        position--;
 
332
                        var count = (ReadInt32 () >> 8) / 24;
 
333
 
 
334
                        ReadExceptionHandlers (
 
335
                                count,
 
336
                                ReadInt32,
 
337
                                ReadInt32);
 
338
                }
 
339
 
 
340
                // inline ?
 
341
                void ReadExceptionHandlers (int count, Func<int> read_entry, Func<int> read_length)
 
342
                {
 
343
                        for (int i = 0; i < count; i++) {
 
344
                                var handler = new ExceptionHandler (
 
345
                                        (ExceptionHandlerType) (read_entry () & 0x7));
 
346
 
 
347
                                handler.TryStart = GetInstruction (read_entry ());
 
348
                                handler.TryEnd = GetInstruction (handler.TryStart.Offset + read_length ());
 
349
 
 
350
                                handler.HandlerStart = GetInstruction (read_entry ());
 
351
                                handler.HandlerEnd = GetInstruction (handler.HandlerStart.Offset + read_length ());
 
352
 
 
353
                                ReadExceptionHandlerSpecific (handler);
 
354
 
 
355
                                this.body.ExceptionHandlers.Add (handler);
 
356
                        }
 
357
                }
 
358
 
 
359
                void ReadExceptionHandlerSpecific (ExceptionHandler handler)
 
360
                {
 
361
                        switch (handler.HandlerType) {
 
362
                        case ExceptionHandlerType.Catch:
 
363
                                handler.CatchType = (TypeReference) reader.LookupToken (ReadToken ());
 
364
                                break;
 
365
                        case ExceptionHandlerType.Filter:
 
366
                                handler.FilterStart = GetInstruction (ReadInt32 ());
 
367
                                handler.FilterEnd = handler.HandlerStart.Previous;
 
368
                                break;
 
369
                        default:
 
370
                                Advance (4);
 
371
                                break;
 
372
                        }
 
373
                }
 
374
 
 
375
                void Align (int align)
 
376
                {
 
377
                        align--;
 
378
                        Advance (((position + align) & ~align) - position);
 
379
                }
 
380
 
 
381
                public MetadataToken ReadToken ()
 
382
                {
 
383
                        return new MetadataToken (ReadUInt32 ());
 
384
                }
 
385
 
 
386
#if !READ_ONLY
 
387
 
 
388
                public ByteBuffer PatchRawMethodBody (MethodDefinition method, CodeWriter writer, out MethodSymbols symbols)
 
389
                {
 
390
                        var buffer = new ByteBuffer ();
 
391
                        symbols = new MethodSymbols (method.Name);
 
392
 
 
393
                        this.method = method;
 
394
                        reader.context = method;
 
395
 
 
396
                        MoveTo (method.RVA);
 
397
 
 
398
                        var flags = ReadByte ();
 
399
 
 
400
                        MetadataToken local_var_token;
 
401
 
 
402
                        switch (flags & 0x3) {
 
403
                        case 0x2: // tiny
 
404
                                buffer.WriteByte (flags);
 
405
                                local_var_token = MetadataToken.Zero;
 
406
                                symbols.code_size = flags >> 2;
 
407
                                PatchRawCode (buffer, symbols.code_size, writer);
 
408
                                break;
 
409
                        case 0x3: // fat
 
410
                                base.position--;
 
411
 
 
412
                                PatchRawFatMethod (buffer, symbols, writer, out local_var_token);
 
413
                                break;
 
414
                        default:
 
415
                                throw new NotSupportedException ();
 
416
                        }
 
417
 
 
418
                        var symbol_reader = reader.module.SymbolReader;
 
419
                        if (symbol_reader != null && writer.metadata.write_symbols) {
 
420
                                symbols.method_token = GetOriginalToken (writer.metadata, method);
 
421
                                symbols.local_var_token = local_var_token;
 
422
                                symbol_reader.Read (symbols);
 
423
                        }
 
424
 
 
425
                        return buffer;
 
426
                }
 
427
 
 
428
                void PatchRawFatMethod (ByteBuffer buffer, MethodSymbols symbols, CodeWriter writer, out MetadataToken local_var_token)
 
429
                {
 
430
                        var flags = ReadUInt16 ();
 
431
                        buffer.WriteUInt16 (flags);
 
432
                        buffer.WriteUInt16 (ReadUInt16 ());
 
433
                        symbols.code_size = ReadInt32 ();
 
434
                        buffer.WriteInt32 (symbols.code_size);
 
435
                        local_var_token = ReadToken ();
 
436
 
 
437
                        if (local_var_token.RID > 0) {
 
438
                                var variables = symbols.variables = ReadVariables (local_var_token);
 
439
                                buffer.WriteUInt32 (variables != null
 
440
                                        ? writer.GetStandAloneSignature (symbols.variables).ToUInt32 ()
 
441
                                        : 0);
 
442
                        } else
 
443
                                buffer.WriteUInt32 (0);
 
444
 
 
445
                        PatchRawCode (buffer, symbols.code_size, writer);
 
446
 
 
447
                        if ((flags & 0x8) != 0)
 
448
                                PatchRawSection (buffer, writer.metadata);
 
449
                }
 
450
 
 
451
                static MetadataToken GetOriginalToken (MetadataBuilder metadata, MethodDefinition method)
 
452
                {
 
453
                        MetadataToken original;
 
454
                        if (metadata.TryGetOriginalMethodToken (method.token, out original))
 
455
                                return original;
 
456
 
 
457
                        return MetadataToken.Zero;
 
458
                }
 
459
 
 
460
                void PatchRawCode (ByteBuffer buffer, int code_size, CodeWriter writer)
 
461
                {
 
462
                        var metadata = writer.metadata;
 
463
                        buffer.WriteBytes (ReadBytes (code_size));
 
464
                        var end = buffer.position;
 
465
                        buffer.position -= code_size;
 
466
 
 
467
                        while (buffer.position < end) {
 
468
                                OpCode opcode;
 
469
                                var il_opcode = buffer.ReadByte ();
 
470
                                if (il_opcode != 0xfe) {
 
471
                                        opcode = OpCodes.OneByteOpCode [il_opcode];
 
472
                                } else {
 
473
                                        var il_opcode2 = buffer.ReadByte ();
 
474
                                        opcode = OpCodes.TwoBytesOpCode [il_opcode2];
 
475
                                }
 
476
 
 
477
                                switch (opcode.OperandType) {
 
478
                                case OperandType.ShortInlineI:
 
479
                                case OperandType.ShortInlineBrTarget:
 
480
                                case OperandType.ShortInlineVar:
 
481
                                case OperandType.ShortInlineArg:
 
482
                                        buffer.position += 1;
 
483
                                        break;
 
484
                                case OperandType.InlineVar:
 
485
                                case OperandType.InlineArg:
 
486
                                        buffer.position += 2;
 
487
                                        break;
 
488
                                case OperandType.InlineBrTarget:
 
489
                                case OperandType.ShortInlineR:
 
490
                                case OperandType.InlineI:
 
491
                                        buffer.position += 4;
 
492
                                        break;
 
493
                                case OperandType.InlineI8:
 
494
                                case OperandType.InlineR:
 
495
                                        buffer.position += 8;
 
496
                                        break;
 
497
                                case OperandType.InlineSwitch:
 
498
                                        var length = buffer.ReadInt32 ();
 
499
                                        buffer.position += length * 4;
 
500
                                        break;
 
501
                                case OperandType.InlineString:
 
502
                                        var @string = GetString (new MetadataToken (buffer.ReadUInt32 ()));
 
503
                                        buffer.position -= 4;
 
504
                                        buffer.WriteUInt32 (
 
505
                                                new MetadataToken (
 
506
                                                        TokenType.String,
 
507
                                                        metadata.user_string_heap.GetStringIndex (@string)).ToUInt32 ());
 
508
                                        break;
 
509
                                case OperandType.InlineSig:
 
510
                                        var call_site = GetCallSite (new MetadataToken (buffer.ReadUInt32 ()));
 
511
                                        buffer.position -= 4;
 
512
                                        buffer.WriteUInt32 (writer.GetStandAloneSignature (call_site).ToUInt32 ());
 
513
                                        break;
 
514
                                case OperandType.InlineTok:
 
515
                                case OperandType.InlineType:
 
516
                                case OperandType.InlineMethod:
 
517
                                case OperandType.InlineField:
 
518
                                        var provider = reader.LookupToken (new MetadataToken (buffer.ReadUInt32 ()));
 
519
                                        buffer.position -= 4;
 
520
                                        buffer.WriteUInt32 (metadata.LookupToken (provider).ToUInt32 ());
 
521
                                        break;
 
522
                                }
 
523
                        }
 
524
                }
 
525
 
 
526
                void PatchRawSection (ByteBuffer buffer, MetadataBuilder metadata)
 
527
                {
 
528
                        var position = base.position;
 
529
                        Align (4);
 
530
                        buffer.WriteBytes (base.position - position);
 
531
 
 
532
                        const byte fat_format = 0x40;
 
533
                        const byte more_sects = 0x80;
 
534
 
 
535
                        var flags = ReadByte ();
 
536
                        if ((flags & fat_format) == 0) {
 
537
                                buffer.WriteByte (flags);
 
538
                                PatchRawSmallSection (buffer, metadata);
 
539
                        } else
 
540
                                PatchRawFatSection (buffer, metadata);
 
541
 
 
542
                        if ((flags & more_sects) != 0)
 
543
                                PatchRawSection (buffer, metadata);
 
544
                }
 
545
 
 
546
                void PatchRawSmallSection (ByteBuffer buffer, MetadataBuilder metadata)
 
547
                {
 
548
                        var length = ReadByte ();
 
549
                        buffer.WriteByte (length);
 
550
                        Advance (2);
 
551
 
 
552
                        buffer.WriteUInt16 (0);
 
553
 
 
554
                        var count = length / 12;
 
555
 
 
556
                        PatchRawExceptionHandlers (buffer, metadata, count, false);
 
557
                }
 
558
 
 
559
                void PatchRawFatSection (ByteBuffer buffer, MetadataBuilder metadata)
 
560
                {
 
561
                        position--;
 
562
                        var length = ReadInt32 ();
 
563
                        buffer.WriteInt32 (length);
 
564
 
 
565
                        var count = (length >> 8) / 24;
 
566
 
 
567
                        PatchRawExceptionHandlers (buffer, metadata, count, true);
 
568
                }
 
569
 
 
570
                void PatchRawExceptionHandlers (ByteBuffer buffer, MetadataBuilder metadata, int count, bool fat_entry)
 
571
                {
 
572
                        const int fat_entry_size = 16;
 
573
                        const int small_entry_size = 6;
 
574
 
 
575
                        for (int i = 0; i < count; i++) {
 
576
                                ExceptionHandlerType handler_type;
 
577
                                if (fat_entry) {
 
578
                                        var type = ReadUInt32 ();
 
579
                                        handler_type = (ExceptionHandlerType) (type & 0x7);
 
580
                                        buffer.WriteUInt32 (type);
 
581
                                } else {
 
582
                                        var type = ReadUInt16 ();
 
583
                                        handler_type = (ExceptionHandlerType) (type & 0x7);
 
584
                                        buffer.WriteUInt16 (type);
 
585
                                }
 
586
 
 
587
                                buffer.WriteBytes (ReadBytes (fat_entry ? fat_entry_size : small_entry_size));
 
588
 
 
589
                                switch (handler_type) {
 
590
                                case ExceptionHandlerType.Catch:
 
591
                                        var exception = reader.LookupToken (ReadToken ());
 
592
                                        buffer.WriteUInt32 (metadata.LookupToken (exception).ToUInt32 ());
 
593
                                        break;
 
594
                                default:
 
595
                                        buffer.WriteUInt32 (ReadUInt32 ());
 
596
                                        break;
 
597
                                }
 
598
                        }
 
599
                }
 
600
 
 
601
#endif
 
602
 
 
603
        }
 
604
}