~ubuntu-branches/ubuntu/wily/monodevelop/wily

« back to all changes in this revision

Viewing changes to contrib/Mono.Cecil/Mono.CompilerServices.SymbolWriterOld/MonoSymbolTable.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2010-02-02 11:39:59 UTC
  • mfrom: (10.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20100202113959-n3u848nfj35yyd03
Tags: 2.2.1+dfsg-1
* New upstream release
* debian/control:
  + Standards version 3.8.4 (no changes needed)
* debian/patches/remove_support_for_non_debian_functionality.patch,
  debian/patches/remove_support_for_soft_debugger.patch,
  debian/patches/remove_support_for_moonlight.patch,
  debian/rules:
  + Split patch into two pieces, to make it easier to enable either
    SDB or Moonlight support with a rebuild
* debian/monodevelop-moonlight.install,
  debian/monodevelop-debugger-sdb.install,
  debian/control:
  + Create packaging data for the Soft Debugger addin and Moonlight addin -
    and comment them out of debian/control as we can't provide them on
    Debian for now

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
// Mono.CSharp.Debugger/MonoSymbolTable.cs
3
 
//
4
 
// Author:
5
 
//   Martin Baulig (martin@ximian.com)
6
 
//
7
 
// (C) 2002 Ximian, Inc.  http://www.ximian.com
8
 
//
9
 
 
10
 
//
11
 
// Permission is hereby granted, free of charge, to any person obtaining
12
 
// a copy of this software and associated documentation files (the
13
 
// "Software"), to deal in the Software without restriction, including
14
 
// without limitation the rights to use, copy, modify, merge, publish,
15
 
// distribute, sublicense, and/or sell copies of the Software, and to
16
 
// permit persons to whom the Software is furnished to do so, subject to
17
 
// the following conditions:
18
 
// 
19
 
// The above copyright notice and this permission notice shall be
20
 
// included in all copies or substantial portions of the Software.
21
 
// 
22
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23
 
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24
 
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25
 
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26
 
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27
 
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28
 
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
 
//
30
 
 
31
 
using System;
32
 
using System.Collections;
33
 
using System.Text;
34
 
using System.IO;
35
 
 
36
 
//
37
 
// Parts which are actually written into the symbol file are marked with
38
 
//
39
 
//         #region This is actually written to the symbol file
40
 
//         #endregion
41
 
//
42
 
// Please do not modify these regions without previously talking to me.
43
 
//
44
 
// All changes to the file format must be synchronized in several places:
45
 
//
46
 
// a) The fields in these regions (and their order) must match the actual
47
 
//    contents of the symbol file.
48
 
//
49
 
//    This helps people to understand the symbol file format without reading
50
 
//    too much source code, ie. you look at the appropriate region and then
51
 
//    you know what's actually in the file.
52
 
//
53
 
//    It is also required to help me enforce b).
54
 
//
55
 
// b) The regions must be kept in sync with the unmanaged code in
56
 
//    mono/metadata/debug-mono-symfile.h
57
 
//
58
 
// When making changes to the file format, you must also increase two version
59
 
// numbers:
60
 
//
61
 
// i)  OffsetTable.Version in this file.
62
 
// ii) MONO_SYMBOL_FILE_VERSION in mono/metadata/debug-mono-symfile.h
63
 
//
64
 
// After doing so, recompile everything, including the debugger.  Symbol files
65
 
// with different versions are incompatible to each other and the debugger and
66
 
// the runtime enfore this, so you need to recompile all your assemblies after
67
 
// changing the file format.
68
 
//
69
 
 
70
 
namespace Mono.CompilerServices.SymbolWriterOld
71
 
{
72
 
        public struct OffsetTable
73
 
        {
74
 
                public const int  Version = 39;
75
 
                public const long Magic   = 0x45e82623fd7fa614;
76
 
 
77
 
                #region This is actually written to the symbol file
78
 
                public int TotalFileSize;
79
 
                public int DataSectionOffset;
80
 
                public int DataSectionSize;
81
 
                public int SourceCount;
82
 
                public int SourceTableOffset;
83
 
                public int SourceTableSize;
84
 
                public int MethodCount;
85
 
                public int MethodTableOffset;
86
 
                public int MethodTableSize;
87
 
                public int TypeCount;
88
 
                #endregion
89
 
 
90
 
                internal OffsetTable (BinaryReader reader)
91
 
                {
92
 
                        TotalFileSize = reader.ReadInt32 ();
93
 
                        DataSectionOffset = reader.ReadInt32 ();
94
 
                        DataSectionSize = reader.ReadInt32 ();
95
 
                        SourceCount = reader.ReadInt32 ();
96
 
                        SourceTableOffset = reader.ReadInt32 ();
97
 
                        SourceTableSize = reader.ReadInt32 ();
98
 
                        MethodCount = reader.ReadInt32 ();
99
 
                        MethodTableOffset = reader.ReadInt32 ();
100
 
                        MethodTableSize = reader.ReadInt32 ();
101
 
                        TypeCount = reader.ReadInt32 ();
102
 
                }
103
 
 
104
 
                internal void Write (BinaryWriter bw)
105
 
                {
106
 
                        bw.Write (TotalFileSize);
107
 
                        bw.Write (DataSectionOffset);
108
 
                        bw.Write (DataSectionSize);
109
 
                        bw.Write (SourceCount);
110
 
                        bw.Write (SourceTableOffset);
111
 
                        bw.Write (SourceTableSize);
112
 
                        bw.Write (MethodCount);
113
 
                        bw.Write (MethodTableOffset);
114
 
                        bw.Write (MethodTableSize);
115
 
                        bw.Write (TypeCount);
116
 
                }
117
 
 
118
 
                public override string ToString ()
119
 
                {
120
 
                        return String.Format (
121
 
                                "OffsetTable [{0} - {1}:{2} - {3}:{4}:{5} - {6}:{7}:{8} - {9}]",
122
 
                                TotalFileSize, DataSectionOffset, DataSectionSize, SourceCount,
123
 
                                SourceTableOffset, SourceTableSize, MethodCount, MethodTableOffset,
124
 
                                MethodTableSize, TypeCount);
125
 
                }
126
 
        }
127
 
 
128
 
        public struct LineNumberEntry
129
 
        {
130
 
                #region This is actually written to the symbol file
131
 
                public readonly int Row;
132
 
                public readonly int Offset;
133
 
                #endregion
134
 
 
135
 
                public LineNumberEntry (int row, int offset)
136
 
                {
137
 
                        this.Row = row;
138
 
                        this.Offset = offset;
139
 
                }
140
 
 
141
 
                public static LineNumberEntry Null = new LineNumberEntry (0, 0);
142
 
 
143
 
                internal LineNumberEntry (BinaryReader reader)
144
 
                {
145
 
                        Row = reader.ReadInt32 ();
146
 
                        Offset = reader.ReadInt32 ();
147
 
                }
148
 
 
149
 
                internal void Write (BinaryWriter bw)
150
 
                {
151
 
                        bw.Write (Row);
152
 
                        bw.Write (Offset);
153
 
                }
154
 
 
155
 
                private class OffsetComparerClass : IComparer
156
 
                {
157
 
                        public int Compare (object a, object b)
158
 
                        {
159
 
                                LineNumberEntry l1 = (LineNumberEntry) a;
160
 
                                LineNumberEntry l2 = (LineNumberEntry) b;
161
 
 
162
 
                                if (l1.Offset < l2.Offset)
163
 
                                        return -1;
164
 
                                else if (l1.Offset > l2.Offset)
165
 
                                        return 1;
166
 
                                else
167
 
                                        return 0;
168
 
                        }
169
 
                }
170
 
 
171
 
                private class RowComparerClass : IComparer
172
 
                {
173
 
                        public int Compare (object a, object b)
174
 
                        {
175
 
                                LineNumberEntry l1 = (LineNumberEntry) a;
176
 
                                LineNumberEntry l2 = (LineNumberEntry) b;
177
 
 
178
 
                                if (l1.Row < l2.Row)
179
 
                                        return -1;
180
 
                                else if (l1.Row > l2.Row)
181
 
                                        return 1;
182
 
                                else
183
 
                                        return 0;
184
 
                        }
185
 
                }
186
 
 
187
 
                public static readonly IComparer OffsetComparer = new OffsetComparerClass ();
188
 
                public static readonly IComparer RowComparer = new RowComparerClass ();
189
 
 
190
 
                public override string ToString ()
191
 
                {
192
 
                        return String.Format ("[Line {0}:{1}]", Row, Offset);
193
 
                }
194
 
        }
195
 
 
196
 
        public class LexicalBlockEntry
197
 
        {
198
 
                public int Index;
199
 
                #region This is actually written to the symbol file
200
 
                public int StartOffset;
201
 
                public int EndOffset;
202
 
                #endregion
203
 
 
204
 
                public LexicalBlockEntry (int index, int start_offset)
205
 
                {
206
 
                        this.Index = index;
207
 
                        this.StartOffset = start_offset;
208
 
                }
209
 
 
210
 
                internal LexicalBlockEntry (int index, MyBinaryReader reader)
211
 
                {
212
 
                        this.Index = index;
213
 
                        this.StartOffset = reader.ReadInt32 ();
214
 
                        this.EndOffset = reader.ReadInt32 ();
215
 
                }
216
 
 
217
 
                public void Close (int end_offset)
218
 
                {
219
 
                        this.EndOffset = end_offset;
220
 
                }
221
 
 
222
 
                internal void Write (MyBinaryWriter bw)
223
 
                {
224
 
                        bw.Write (StartOffset);
225
 
                        bw.Write (EndOffset);
226
 
                }
227
 
 
228
 
                public override string ToString ()
229
 
                {
230
 
                        return String.Format ("[LexicalBlock {0}:{1}]", StartOffset, EndOffset);
231
 
                }
232
 
        }
233
 
 
234
 
        public struct LocalVariableEntry
235
 
        {
236
 
                #region This is actually written to the symbol file
237
 
                public readonly int Index;
238
 
                public readonly string Name;
239
 
                public readonly byte[] Signature;
240
 
                public readonly int BlockIndex;
241
 
                #endregion
242
 
 
243
 
                public LocalVariableEntry (int Index, string Name, byte[] Signature, int BlockIndex)
244
 
                {
245
 
                        this.Index = Index;
246
 
                        this.Name = Name;
247
 
                        this.Signature = Signature;
248
 
                        this.BlockIndex = BlockIndex;
249
 
                }
250
 
 
251
 
                internal LocalVariableEntry (MyBinaryReader reader)
252
 
                {
253
 
                        Index = reader.ReadLeb128 ();
254
 
                        Name = reader.ReadString ();
255
 
                        int sig_length = reader.ReadLeb128 ();
256
 
                        Signature = reader.ReadBytes (sig_length);
257
 
                        BlockIndex = reader.ReadLeb128 ();
258
 
                }
259
 
 
260
 
                internal void Write (MonoSymbolFile file, MyBinaryWriter bw)
261
 
                {
262
 
                        bw.WriteLeb128 (Index);
263
 
                        bw.Write (Name);
264
 
                        bw.WriteLeb128 ((int) Signature.Length);
265
 
                        bw.Write (Signature);
266
 
                        bw.WriteLeb128 (BlockIndex);
267
 
                }
268
 
 
269
 
                public override string ToString ()
270
 
                {
271
 
                        return String.Format ("[LocalVariable {0}]", Name);
272
 
                }
273
 
        }
274
 
 
275
 
        public class SourceFileEntry
276
 
        {
277
 
                #region This is actually written to the symbol file
278
 
                public readonly int Index;
279
 
                int Count;
280
 
                int NamespaceCount;
281
 
                int NameOffset;
282
 
                int MethodOffset;
283
 
                int NamespaceTableOffset;
284
 
                #endregion
285
 
 
286
 
                MonoSymbolFile file;
287
 
                string file_name;
288
 
                ArrayList methods;
289
 
                ArrayList namespaces;
290
 
                bool creating;
291
 
 
292
 
                public static int Size {
293
 
                        get { return 24; }
294
 
                }
295
 
 
296
 
                public SourceFileEntry (MonoSymbolFile file, string file_name)
297
 
                {
298
 
                        this.file = file;
299
 
                        this.file_name = file_name;
300
 
                        this.Index = file.AddSource (this);
301
 
 
302
 
                        creating = true;
303
 
                        methods = new ArrayList ();
304
 
                        namespaces = new ArrayList ();
305
 
                }
306
 
 
307
 
                public void DefineMethod (string name, int token, LocalVariableEntry[] locals,
308
 
                                          LineNumberEntry[] lines, LexicalBlockEntry[] blocks,
309
 
                                          int start, int end, int namespace_id)
310
 
                {
311
 
                        if (!creating)
312
 
                                throw new InvalidOperationException ();
313
 
 
314
 
                        MethodEntry entry = new MethodEntry (
315
 
                                file, this, name, (int) token, locals, lines, blocks,
316
 
                                start, end, namespace_id);
317
 
 
318
 
                        methods.Add (entry);
319
 
                        file.AddMethod (entry);
320
 
                }
321
 
 
322
 
                public int DefineNamespace (string name, string[] using_clauses, int parent)
323
 
                {
324
 
                        if (!creating)
325
 
                                throw new InvalidOperationException ();
326
 
 
327
 
                        int index = file.GetNextNamespaceIndex ();
328
 
                        NamespaceEntry ns = new NamespaceEntry (name, index, using_clauses, parent);
329
 
                        namespaces.Add (ns);
330
 
                        return index;
331
 
                }
332
 
 
333
 
                internal void WriteData (MyBinaryWriter bw)
334
 
                {
335
 
                        NameOffset = (int) bw.BaseStream.Position;
336
 
                        bw.Write (file_name);
337
 
 
338
 
                        ArrayList list = new ArrayList ();
339
 
                        foreach (MethodEntry entry in methods)
340
 
                                list.Add (entry.Write (file, bw));
341
 
                        list.Sort ();
342
 
                        Count = list.Count;
343
 
 
344
 
                        MethodOffset = (int) bw.BaseStream.Position;
345
 
                        foreach (MethodSourceEntry method in list)
346
 
                                method.Write (bw);
347
 
 
348
 
                        NamespaceCount = namespaces.Count;
349
 
                        NamespaceTableOffset = (int) bw.BaseStream.Position;
350
 
                        foreach (NamespaceEntry ns in namespaces)
351
 
                                ns.Write (file, bw);
352
 
                }
353
 
 
354
 
                internal void Write (BinaryWriter bw)
355
 
                {
356
 
                        bw.Write (Index);
357
 
                        bw.Write (Count);
358
 
                        bw.Write (NamespaceCount);
359
 
                        bw.Write (NameOffset);
360
 
                        bw.Write (MethodOffset);
361
 
                        bw.Write (NamespaceTableOffset);
362
 
                }
363
 
 
364
 
                internal SourceFileEntry (MonoSymbolFile file, BinaryReader reader)
365
 
                {
366
 
                        this.file = file;
367
 
 
368
 
                        Index = reader.ReadInt32 ();
369
 
                        Count = reader.ReadInt32 ();
370
 
                        NamespaceCount = reader.ReadInt32 ();
371
 
                        NameOffset = reader.ReadInt32 ();
372
 
                        MethodOffset = reader.ReadInt32 ();
373
 
                        NamespaceTableOffset = reader.ReadInt32 ();
374
 
 
375
 
                        file_name = file.ReadString (NameOffset);
376
 
                }
377
 
 
378
 
                public string FileName {
379
 
                        get { return file_name; }
380
 
                }
381
 
 
382
 
                public MethodSourceEntry[] Methods {
383
 
                        get {
384
 
                                if (creating)
385
 
                                        throw new InvalidOperationException ();
386
 
 
387
 
                                BinaryReader reader = file.BinaryReader;
388
 
                                int old_pos = (int) reader.BaseStream.Position;
389
 
 
390
 
                                reader.BaseStream.Position = MethodOffset;
391
 
                                ArrayList list = new ArrayList ();
392
 
                                for (int i = 0; i < Count; i ++)
393
 
                                        list.Add (new MethodSourceEntry (reader));
394
 
                                reader.BaseStream.Position = old_pos;
395
 
 
396
 
                                MethodSourceEntry[] retval = new MethodSourceEntry [Count];
397
 
                                list.CopyTo (retval, 0);
398
 
                                return retval;
399
 
                        }
400
 
                }
401
 
 
402
 
                public NamespaceEntry[] Namespaces {
403
 
                        get {
404
 
                                if (creating)
405
 
                                        throw new InvalidOperationException ();
406
 
 
407
 
                                MyBinaryReader reader = file.BinaryReader;
408
 
                                int old_pos = (int) reader.BaseStream.Position;
409
 
 
410
 
                                reader.BaseStream.Position = NamespaceTableOffset;
411
 
                                ArrayList list = new ArrayList ();
412
 
                                for (int i = 0; i < NamespaceCount; i ++)
413
 
                                        list.Add (new NamespaceEntry (file, reader));
414
 
                                reader.BaseStream.Position = old_pos;
415
 
 
416
 
                                NamespaceEntry[] retval = new NamespaceEntry [list.Count];
417
 
                                list.CopyTo (retval, 0);
418
 
                                return retval;
419
 
                        }
420
 
                }
421
 
 
422
 
                public override string ToString ()
423
 
                {
424
 
                        return String.Format ("SourceFileEntry ({0}:{1}:{2})",
425
 
                                              Index, file_name, Count);
426
 
                }
427
 
        }
428
 
 
429
 
        public struct MethodSourceEntry : IComparable
430
 
        {
431
 
                #region This is actually written to the symbol file
432
 
                public readonly int Index;
433
 
                public readonly int FileOffset;
434
 
                public readonly int StartRow;
435
 
                public readonly int EndRow;
436
 
                #endregion
437
 
 
438
 
                public MethodSourceEntry (int index, int file_offset, int start, int end)
439
 
                {
440
 
                        this.Index = index;
441
 
                        this.FileOffset = file_offset;
442
 
                        this.StartRow = start;
443
 
                        this.EndRow = end;
444
 
                }
445
 
 
446
 
                internal MethodSourceEntry (BinaryReader reader)
447
 
                {
448
 
                        Index = reader.ReadInt32 ();
449
 
                        FileOffset = reader.ReadInt32 ();
450
 
                        StartRow = reader.ReadInt32 ();
451
 
                        EndRow = reader.ReadInt32 ();
452
 
                }
453
 
 
454
 
                public static int Size {
455
 
                        get { return 16; }
456
 
                }
457
 
 
458
 
                internal void Write (BinaryWriter bw)
459
 
                {
460
 
                        bw.Write (Index);
461
 
                        bw.Write (FileOffset);
462
 
                        bw.Write (StartRow);
463
 
                        bw.Write (EndRow);
464
 
                }
465
 
 
466
 
                public int CompareTo (object obj)
467
 
                {
468
 
                        MethodSourceEntry method = (MethodSourceEntry) obj;
469
 
 
470
 
                        if (method.StartRow < StartRow)
471
 
                                return -1;
472
 
                        else if (method.StartRow > StartRow)
473
 
                                return 1;
474
 
                        else
475
 
                                return 0;
476
 
                }
477
 
 
478
 
                public override string ToString ()
479
 
                {
480
 
                        return String.Format ("MethodSourceEntry ({0}:{1}:{2}:{3})",
481
 
                                              Index, FileOffset, StartRow, EndRow);
482
 
                }
483
 
        }
484
 
 
485
 
        public struct MethodIndexEntry
486
 
        {
487
 
                #region This is actually written to the symbol file
488
 
                public readonly int FileOffset;
489
 
                public readonly int Token;
490
 
                #endregion
491
 
 
492
 
                public static int Size {
493
 
                        get { return 8; }
494
 
                }
495
 
 
496
 
                public MethodIndexEntry (int offset, int token)
497
 
                {
498
 
                        this.FileOffset = offset;
499
 
                        this.Token = token;
500
 
                }
501
 
 
502
 
                internal MethodIndexEntry (BinaryReader reader)
503
 
                {
504
 
                        FileOffset = reader.ReadInt32 ();
505
 
                        Token = reader.ReadInt32 ();
506
 
                }
507
 
 
508
 
                internal void Write (BinaryWriter bw)
509
 
                {
510
 
                        bw.Write (FileOffset);
511
 
                        bw.Write (Token);
512
 
                }
513
 
 
514
 
                public override string ToString ()
515
 
                {
516
 
                        return String.Format ("MethodIndexEntry ({0}:{1:x})",
517
 
                                              FileOffset, Token);
518
 
                }
519
 
        }
520
 
 
521
 
        public class MethodEntry : IComparable
522
 
        {
523
 
                #region This is actually written to the symbol file
524
 
                public readonly int SourceFileIndex;
525
 
                public readonly int Token;
526
 
                public readonly int StartRow;
527
 
                public readonly int EndRow;
528
 
                public readonly int NumLocals;
529
 
                public readonly int NumLineNumbers;
530
 
                public readonly int NamespaceID;
531
 
                public readonly bool LocalNamesAmbiguous;
532
 
 
533
 
                int NameOffset;
534
 
                int TypeIndexTableOffset;
535
 
                int LocalVariableTableOffset;
536
 
                int LineNumberTableOffset;
537
 
                int NumLexicalBlocks;
538
 
                int LexicalBlockTableOffset;
539
 
                #endregion
540
 
 
541
 
                int index;
542
 
                int file_offset;
543
 
 
544
 
                public readonly SourceFileEntry SourceFile;
545
 
                public readonly LineNumberEntry[] LineNumbers;
546
 
                public readonly int[] LocalTypeIndices;
547
 
                public readonly LocalVariableEntry[] Locals;
548
 
                public readonly LexicalBlockEntry[] LexicalBlocks;
549
 
 
550
 
                public readonly MonoSymbolFile SymbolFile;
551
 
 
552
 
                public int Index {
553
 
                        get { return index; }
554
 
                        set { index = value; }
555
 
                }
556
 
 
557
 
                public static int Size {
558
 
                        get { return 52; }
559
 
                }
560
 
 
561
 
                internal MethodEntry (MonoSymbolFile file, MyBinaryReader reader, int index)
562
 
                {
563
 
                        this.SymbolFile = file;
564
 
                        this.index = index;
565
 
                        SourceFileIndex = reader.ReadInt32 ();
566
 
                        Token = reader.ReadInt32 ();
567
 
                        StartRow = reader.ReadInt32 ();
568
 
                        EndRow = reader.ReadInt32 ();
569
 
                        NumLocals = reader.ReadInt32 ();
570
 
                        NumLineNumbers = reader.ReadInt32 ();
571
 
                        NameOffset = reader.ReadInt32 ();
572
 
                        TypeIndexTableOffset = reader.ReadInt32 ();
573
 
                        LocalVariableTableOffset = reader.ReadInt32 ();
574
 
                        LineNumberTableOffset = reader.ReadInt32 ();
575
 
                        NumLexicalBlocks = reader.ReadInt32 ();
576
 
                        LexicalBlockTableOffset = reader.ReadInt32 ();
577
 
                        NamespaceID = reader.ReadInt32 ();
578
 
                        LocalNamesAmbiguous = reader.ReadInt32 () != 0;
579
 
 
580
 
                        SourceFile = file.GetSourceFile (SourceFileIndex);
581
 
 
582
 
                        if (LineNumberTableOffset != 0) {
583
 
                                long old_pos = reader.BaseStream.Position;
584
 
                                reader.BaseStream.Position = LineNumberTableOffset;
585
 
 
586
 
                                LineNumbers = new LineNumberEntry [NumLineNumbers];
587
 
 
588
 
                                for (int i = 0; i < NumLineNumbers; i++)
589
 
                                        LineNumbers [i] = new LineNumberEntry (reader);
590
 
 
591
 
                                reader.BaseStream.Position = old_pos;
592
 
                        }
593
 
 
594
 
                        if (LocalVariableTableOffset != 0) {
595
 
                                long old_pos = reader.BaseStream.Position;
596
 
                                reader.BaseStream.Position = LocalVariableTableOffset;
597
 
 
598
 
                                Locals = new LocalVariableEntry [NumLocals];
599
 
 
600
 
                                for (int i = 0; i < NumLocals; i++)
601
 
                                        Locals [i] = new LocalVariableEntry (reader);
602
 
 
603
 
                                reader.BaseStream.Position = old_pos;
604
 
                        }
605
 
 
606
 
                        if (TypeIndexTableOffset != 0) {
607
 
                                long old_pos = reader.BaseStream.Position;
608
 
                                reader.BaseStream.Position = TypeIndexTableOffset;
609
 
 
610
 
                                LocalTypeIndices = new int [NumLocals];
611
 
 
612
 
                                for (int i = 0; i < NumLocals; i++)
613
 
                                        LocalTypeIndices [i] = reader.ReadInt32 ();
614
 
 
615
 
                                reader.BaseStream.Position = old_pos;
616
 
                        }
617
 
 
618
 
                        if (LexicalBlockTableOffset != 0) {
619
 
                                long old_pos = reader.BaseStream.Position;
620
 
                                reader.BaseStream.Position = LexicalBlockTableOffset;
621
 
 
622
 
                                LexicalBlocks = new LexicalBlockEntry [NumLexicalBlocks];
623
 
                                for (int i = 0; i < NumLexicalBlocks; i++)
624
 
                                        LexicalBlocks [i] = new LexicalBlockEntry (i, reader);
625
 
 
626
 
                                reader.BaseStream.Position = old_pos;
627
 
                        }
628
 
                }
629
 
 
630
 
                internal MethodEntry (MonoSymbolFile file, SourceFileEntry source,
631
 
                                      string name, int token, LocalVariableEntry[] locals,
632
 
                                      LineNumberEntry[] lines, LexicalBlockEntry[] blocks,
633
 
                                      int start_row, int end_row, int namespace_id)
634
 
                {
635
 
                        this.SymbolFile = file;
636
 
 
637
 
                        index = -1;
638
 
 
639
 
                        Token = token;
640
 
                        SourceFileIndex = source.Index;
641
 
                        SourceFile = source;
642
 
                        StartRow = start_row;
643
 
                        EndRow = end_row;
644
 
                        NamespaceID = namespace_id;
645
 
                        LexicalBlocks = blocks;
646
 
                        NumLexicalBlocks = LexicalBlocks != null ? LexicalBlocks.Length : 0;
647
 
 
648
 
                        LineNumbers = BuildLineNumberTable (lines);
649
 
                        NumLineNumbers = LineNumbers.Length;
650
 
 
651
 
                        file.NumLineNumbers += NumLineNumbers;
652
 
 
653
 
                        NumLocals = locals != null ? locals.Length : 0;
654
 
                        Locals = locals;
655
 
 
656
 
                        if (NumLocals <= 32) {
657
 
                                // Most of the time, the O(n^2) factor is actually
658
 
                                // less than the cost of allocating the hash table,
659
 
                                // 32 is a rough number obtained through some testing.
660
 
                                
661
 
                                for (int i = 0; i < NumLocals; i ++) {
662
 
                                        string nm = locals [i].Name;
663
 
                                        
664
 
                                        for (int j = i + 1; j < NumLocals; j ++) {
665
 
                                                if (locals [j].Name == nm) {
666
 
                                                        LocalNamesAmbiguous = true;
667
 
                                                        goto locals_check_done;
668
 
                                                }
669
 
                                        }
670
 
                                }
671
 
                        locals_check_done :
672
 
                                ;
673
 
                        } else {
674
 
                                Hashtable local_names = new Hashtable ();
675
 
                                foreach (LocalVariableEntry local in locals) {
676
 
                                        if (local_names.Contains (local.Name)) {
677
 
                                                LocalNamesAmbiguous = true;
678
 
                                                break;
679
 
                                        }
680
 
                                        local_names.Add (local.Name, local);
681
 
                                }
682
 
                        }
683
 
 
684
 
                        LocalTypeIndices = new int [NumLocals];
685
 
                        for (int i = 0; i < NumLocals; i++)
686
 
                                LocalTypeIndices [i] = file.GetNextTypeIndex ();
687
 
                }
688
 
                
689
 
                static LineNumberEntry [] tmp_buff = new LineNumberEntry [20];
690
 
 
691
 
                // BuildLineNumberTable() eliminates duplicate line numbers and ensures
692
 
                // we aren't going "backwards" since this would counfuse the runtime's
693
 
                // debugging code (and the debugger).
694
 
                //
695
 
                // In the line number table, the "offset" field most be strictly
696
 
                // monotonic increasing; that is, the next entry must not have an offset
697
 
                // which is equal to or less than the current one.
698
 
                //
699
 
                // The most common case is that our input (ie. the line number table as
700
 
                // we get it from mcs) contains several entries with the same offset
701
 
                // (and different line numbers) - but it may also happen that the offset
702
 
                // is decreasing (this can be considered as an exception, such lines will
703
 
                // simply be discarded).
704
 
                LineNumberEntry[] BuildLineNumberTable (LineNumberEntry[] line_numbers)
705
 
                {
706
 
                        int pos = 0;
707
 
                        int last_offset = -1;
708
 
                        int last_row = -1;
709
 
 
710
 
                        if (line_numbers == null)
711
 
                                return new LineNumberEntry [0];
712
 
                        
713
 
                        if (tmp_buff.Length < (line_numbers.Length + 1))
714
 
                                tmp_buff = new LineNumberEntry [(line_numbers.Length + 1) * 2];
715
 
 
716
 
                        for (int i = 0; i < line_numbers.Length; i++) {
717
 
                                LineNumberEntry line = line_numbers [i];
718
 
 
719
 
                                if (line.Offset > last_offset) {
720
 
                                        if (last_row >= 0)
721
 
                                                tmp_buff [pos ++] = new LineNumberEntry (last_row, last_offset);
722
 
                                        last_row = line.Row;
723
 
                                        last_offset = line.Offset;
724
 
                                } else if (line.Row > last_row) {
725
 
                                        last_row = line.Row;
726
 
                                }
727
 
                        }
728
 
 
729
 
                        if (last_row >= 0)
730
 
                                tmp_buff [pos ++] = new LineNumberEntry (last_row, last_offset);
731
 
 
732
 
                        LineNumberEntry [] retval = new LineNumberEntry [pos];
733
 
                        Array.Copy (tmp_buff, retval, pos);
734
 
                        return retval;
735
 
                }
736
 
 
737
 
                internal MethodSourceEntry Write (MonoSymbolFile file, MyBinaryWriter bw)
738
 
                {
739
 
                        if (index <= 0)
740
 
                                throw new InvalidOperationException ();
741
 
 
742
 
                        NameOffset = (int) bw.BaseStream.Position;
743
 
 
744
 
                        TypeIndexTableOffset = (int) bw.BaseStream.Position;
745
 
 
746
 
                        for (int i = 0; i < NumLocals; i++)
747
 
                                bw.Write (LocalTypeIndices [i]);
748
 
 
749
 
                        LocalVariableTableOffset = (int) bw.BaseStream.Position;
750
 
                        for (int i = 0; i < NumLocals; i++)
751
 
                                Locals [i].Write (file, bw);
752
 
                        file.LocalCount += NumLocals;
753
 
 
754
 
                        LineNumberTableOffset = (int) bw.BaseStream.Position;
755
 
                        for (int i = 0; i < NumLineNumbers; i++)
756
 
                                LineNumbers [i].Write (bw);
757
 
                        file.LineNumberCount += NumLineNumbers;
758
 
 
759
 
                        LexicalBlockTableOffset = (int) bw.BaseStream.Position;
760
 
                        for (int i = 0; i < NumLexicalBlocks; i++)
761
 
                                LexicalBlocks [i].Write (bw);
762
 
                        file_offset = (int) bw.BaseStream.Position;
763
 
 
764
 
                        bw.Write (SourceFileIndex);
765
 
                        bw.Write (Token);
766
 
                        bw.Write (StartRow);
767
 
                        bw.Write (EndRow);
768
 
                        bw.Write (NumLocals);
769
 
                        bw.Write (NumLineNumbers);
770
 
                        bw.Write (NameOffset);
771
 
                        bw.Write (TypeIndexTableOffset);
772
 
                        bw.Write (LocalVariableTableOffset);
773
 
                        bw.Write (LineNumberTableOffset);
774
 
                        bw.Write (NumLexicalBlocks);
775
 
                        bw.Write (LexicalBlockTableOffset);
776
 
                        bw.Write (NamespaceID);
777
 
                        bw.Write (LocalNamesAmbiguous ? 1 : 0);
778
 
 
779
 
                        return new MethodSourceEntry (index, file_offset, StartRow, EndRow);
780
 
                }
781
 
 
782
 
                internal void WriteIndex (BinaryWriter bw)
783
 
                {
784
 
                        new MethodIndexEntry (file_offset, Token).Write (bw);
785
 
                }
786
 
 
787
 
                public int CompareTo (object obj)
788
 
                {
789
 
                        MethodEntry method = (MethodEntry) obj;
790
 
 
791
 
                        if (method.Token < Token)
792
 
                                return 1;
793
 
                        else if (method.Token > Token)
794
 
                                return -1;
795
 
                        else
796
 
                                return 0;
797
 
                }
798
 
 
799
 
                public override string ToString ()
800
 
                {
801
 
                        return String.Format ("[Method {0}:{1}:{2}:{3}:{4} - {6}:{7} - {5}]",
802
 
                                              index, Token, SourceFileIndex, StartRow, EndRow,
803
 
                                              SourceFile, NumLocals, NumLineNumbers);
804
 
                }
805
 
        }
806
 
 
807
 
        public struct NamespaceEntry
808
 
        {
809
 
                #region This is actually written to the symbol file
810
 
                public readonly string Name;
811
 
                public readonly int Index;
812
 
                public readonly int Parent;
813
 
                public readonly string[] UsingClauses;
814
 
                #endregion
815
 
 
816
 
                public NamespaceEntry (string name, int index, string[] using_clauses, int parent)
817
 
                {
818
 
                        this.Name = name;
819
 
                        this.Index = index;
820
 
                        this.Parent = parent;
821
 
                        this.UsingClauses = using_clauses != null ? using_clauses : new string [0];
822
 
                }
823
 
 
824
 
                internal NamespaceEntry (MonoSymbolFile file, MyBinaryReader reader)
825
 
                {
826
 
                        Name = reader.ReadString ();
827
 
                        Index = reader.ReadLeb128 ();
828
 
                        Parent = reader.ReadLeb128 ();
829
 
 
830
 
                        int count = reader.ReadLeb128 ();
831
 
                        UsingClauses = new string [count];
832
 
                        for (int i = 0; i < count; i++)
833
 
                                UsingClauses [i] = reader.ReadString ();
834
 
                }
835
 
 
836
 
                internal void Write (MonoSymbolFile file, MyBinaryWriter bw)
837
 
                {
838
 
                        bw.Write (Name);
839
 
                        bw.WriteLeb128 (Index);
840
 
                        bw.WriteLeb128 (Parent);
841
 
                        bw.WriteLeb128 (UsingClauses.Length);
842
 
                        foreach (string uc in UsingClauses)
843
 
                                bw.Write (uc);
844
 
                }
845
 
 
846
 
                public override string ToString ()
847
 
                {
848
 
                        return String.Format ("[Namespace {0}:{1}:{2}]", Name, Index, Parent);
849
 
                }
850
 
        }
851
 
}