forgot to remove dead code
[mono.git] / mcs / class / Mono.CSharp.Debugger / MonoSymbolTable.cs
index 93ddeef78916ea011477e4836d030ff01b7b86f6..723643f52cab0dc361d43cd804bc2fe04280ff9c 100644 (file)
@@ -18,7 +18,7 @@ namespace Mono.CSharp.Debugger
 {
        public struct OffsetTable
        {
-               public const int  Version = 33;
+               public const int  Version = 35;
                public const long Magic   = 0x45e82623fd7fa614;
 
                public int TotalFileSize;
@@ -136,17 +136,56 @@ namespace Mono.CSharp.Debugger
                }
        }
 
+       public class LexicalBlockEntry
+       {
+               public int Index;
+               public int StartOffset;
+               public int EndOffset;
+
+               public LexicalBlockEntry (int index, int start_offset)
+               {
+                       this.Index = index;
+                       this.StartOffset = start_offset;
+               }
+
+               internal LexicalBlockEntry (int index, BinaryReader reader)
+               {
+                       this.Index = index;
+                       this.StartOffset = reader.ReadInt32 ();
+                       this.EndOffset = reader.ReadInt32 ();
+               }
+
+               public void Close (int end_offset)
+               {
+                       this.EndOffset = end_offset;
+               }
+
+               internal void Write (BinaryWriter bw)
+               {
+                       bw.Write (StartOffset);
+                       bw.Write (EndOffset);
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("[LexicalBlock {0}:{1}]", StartOffset, EndOffset);
+               }
+       }
+
        public struct LocalVariableEntry
        {
                public readonly string Name;
                public readonly FieldAttributes Attributes;
                public readonly byte[] Signature;
+               public readonly int BlockIndex;
 
-               public LocalVariableEntry (string Name, FieldAttributes Attributes, byte[] Signature)
+               public LocalVariableEntry (string Name, FieldAttributes Attributes, byte[] Signature,
+                                          int BlockIndex)
                {
                        this.Name = Name;
                        this.Attributes = Attributes;
                        this.Signature = Signature;
+                       this.BlockIndex = BlockIndex;
                }
 
                internal LocalVariableEntry (BinaryReader reader)
@@ -157,6 +196,7 @@ namespace Mono.CSharp.Debugger
                        Attributes = (FieldAttributes) reader.ReadInt32 ();
                        int sig_length = reader.ReadInt32 ();
                        Signature = reader.ReadBytes (sig_length);
+                       BlockIndex = reader.ReadInt32 ();
                }
 
                internal void Write (MonoSymbolFile file, BinaryWriter bw)
@@ -165,6 +205,7 @@ namespace Mono.CSharp.Debugger
                        bw.Write ((int) Attributes);
                        bw.Write ((int) Signature.Length);
                        bw.Write (Signature);
+                       bw.Write (BlockIndex);
                }
 
                public override string ToString ()
@@ -199,13 +240,14 @@ namespace Mono.CSharp.Debugger
                }
 
                public void DefineMethod (MethodBase method, int token, LocalVariableEntry[] locals,
-                                         LineNumberEntry[] lines, int start, int end, int namespace_id)
+                                         LineNumberEntry[] lines, LexicalBlockEntry[] blocks,
+                                         int start, int end, int namespace_id)
                {
                        if (!creating)
                                throw new InvalidOperationException ();
 
                        MethodEntry entry = new MethodEntry (
-                               file, this, method, token, locals, lines, start, end, namespace_id);
+                               file, this, method, token, locals, lines, blocks, start, end, namespace_id);
 
                        methods.Add (entry);
                        file.AddMethod (entry);
@@ -405,26 +447,30 @@ namespace Mono.CSharp.Debugger
                public readonly int NumLocals;
                public readonly int NumLineNumbers;
                public readonly int NamespaceID;
+               public readonly bool LocalNamesAmbiguous;
 
                int NameOffset;
                int FullNameOffset;
                int TypeIndexTableOffset;
                int LocalVariableTableOffset;
                int LineNumberTableOffset;
+               int NumLexicalBlocks;
+               int LexicalBlockTableOffset;
                #endregion
 
-               int index;
                int file_offset;
                string name;
                string full_name;
                MethodIndexEntry index_entry;
 
+               public readonly int Index;
                public readonly SourceFileEntry SourceFile;
                public readonly LineNumberEntry[] LineNumbers;
                public readonly int[] ParamTypeIndices;
                public readonly int[] LocalTypeIndices;
                public readonly LocalVariableEntry[] Locals;
                public readonly Type[] LocalTypes;
+               public readonly LexicalBlockEntry[] LexicalBlocks;
 
                public readonly MonoSymbolFile SymbolFile;
 
@@ -447,7 +493,7 @@ namespace Mono.CSharp.Debugger
                internal MethodEntry (MonoSymbolFile file, BinaryReader reader, int index)
                {
                        this.SymbolFile = file;
-                       this.index = index;
+                       this.Index = index;
                        SourceFileIndex = reader.ReadInt32 ();
                        Token = reader.ReadInt32 ();
                        StartRow = reader.ReadInt32 ();
@@ -461,7 +507,10 @@ namespace Mono.CSharp.Debugger
                        TypeIndexTableOffset = reader.ReadInt32 ();
                        LocalVariableTableOffset = reader.ReadInt32 ();
                        LineNumberTableOffset = reader.ReadInt32 ();
+                       NumLexicalBlocks = reader.ReadInt32 ();
+                       LexicalBlockTableOffset = reader.ReadInt32 ();
                        NamespaceID = reader.ReadInt32 ();
+                       LocalNamesAmbiguous = reader.ReadInt32 () != 0;
 
                        name = file.ReadString (NameOffset);
                        full_name = file.ReadString (FullNameOffset);
@@ -512,14 +561,26 @@ namespace Mono.CSharp.Debugger
 
                                reader.BaseStream.Position = old_pos;
                        }
+
+                       if (LexicalBlockTableOffset != 0) {
+                               long old_pos = reader.BaseStream.Position;
+                               reader.BaseStream.Position = LexicalBlockTableOffset;
+
+                               LexicalBlocks = new LexicalBlockEntry [NumLexicalBlocks];
+                               for (int i = 0; i < NumLexicalBlocks; i++)
+                                       LexicalBlocks [i] = new LexicalBlockEntry (i, reader);
+
+                               reader.BaseStream.Position = old_pos;
+                       }
                }
 
                internal MethodEntry (MonoSymbolFile file, SourceFileEntry source, MethodBase method,
                                      int token, LocalVariableEntry[] locals, LineNumberEntry[] lines,
-                                     int start_row, int end_row, int namespace_id)
+                                     LexicalBlockEntry[] blocks, int start_row, int end_row,
+                                     int namespace_id)
                {
                        this.SymbolFile = file;
-                       index = file.GetNextMethodIndex ();
+                       Index = file.GetNextMethodIndex ();
 
                        Token = token;
                        SourceFileIndex = source.Index;
@@ -527,29 +588,39 @@ namespace Mono.CSharp.Debugger
                        StartRow = start_row;
                        EndRow = end_row;
                        NamespaceID = namespace_id;
+                       LexicalBlocks = blocks;
+                       NumLexicalBlocks = LexicalBlocks.Length;
 
-                       LineNumbers = BuildLineNumberTable (lines);
+                       LineNumbers = lines;
                        NumLineNumbers = LineNumbers.Length;
 
                        ParameterInfo[] parameters = method.GetParameters ();
                        if (parameters == null)
                                parameters = new ParameterInfo [0];
-
-                       StringBuilder sb = new StringBuilder ();
-                       sb.Append (method.DeclaringType.FullName);
-                       sb.Append (".");
-                       sb.Append (method.Name);
-                       sb.Append ("(");
-                       for (int i = 0; i < parameters.Length; i++) {
-                               if (i > 0)
-                                       sb.Append (",");
-                               sb.Append (parameters [i].ParameterType.FullName);
+                       
+                       if (parameters.Length == 0)
+                               full_name = method.DeclaringType.FullName + "." + method.Name + "()";
+                       else if (parameters.Length == 1)
+                               full_name = method.DeclaringType.FullName + "." + method.Name + "(" + parameters [0].ParameterType.FullName +  ")";
+                       else if (parameters.Length == 2)
+                               full_name = method.DeclaringType.FullName + "." + method.Name + "(" + parameters [0].ParameterType.FullName + "," + parameters [1].ParameterType.FullName + ")";
+                       else {
+                               StringBuilder sb = new StringBuilder ();
+                               sb.Append (method.DeclaringType.FullName);
+                               sb.Append (".");
+                               sb.Append (method.Name);
+                               sb.Append ("(");
+                               for (int i = 0; i < parameters.Length; i++) {
+                                       if (i > 0)
+                                               sb.Append (",");
+                                       sb.Append (parameters [i].ParameterType.FullName);
+                               }
+                               sb.Append (")");
+                               full_name = sb.ToString ();
                        }
-                       sb.Append (")");
 
                        name = method.Name;
-                       full_name = sb.ToString ();
-
+                       
                        NumParameters = parameters.Length;
                        ParamTypeIndices = new int [NumParameters];
                        for (int i = 0; i < NumParameters; i++)
@@ -558,6 +629,34 @@ namespace Mono.CSharp.Debugger
                        NumLocals = locals.Length;
                        Locals = locals;
 
+                       if (NumLocals <= 32) {
+                               // Most of the time, the O(n^2) factor is actually
+                               // less than the cost of allocating the hash table,
+                               // 32 is a rough number obtained through some testing.
+                               
+                               for (int i = 0; i < NumLocals; i ++) {
+                                       string nm = locals [i].Name;
+                                       
+                                       for (int j = i + 1; j < NumLocals; j ++) {
+                                               if (locals [j].Name == nm) {
+                                                       LocalNamesAmbiguous = true;
+                                                       goto locals_check_done;
+                                               }
+                                       }
+                               }
+                       locals_check_done :
+                               ;
+                       } else {
+                               Hashtable local_names = new Hashtable ();
+                               foreach (LocalVariableEntry local in locals) {
+                                       if (local_names.Contains (local.Name)) {
+                                               LocalNamesAmbiguous = true;
+                                               break;
+                                       }
+                                       local_names.Add (local.Name, local);
+                               }
+                       }
+
                        LocalTypeIndices = new int [NumLocals];
                        for (int i = 0; i < NumLocals; i++)
                                LocalTypeIndices [i] = file.GetNextTypeIndex ();
@@ -565,33 +664,6 @@ namespace Mono.CSharp.Debugger
                        ClassTypeIndex = file.DefineType (method.ReflectedType);
                }
 
-               LineNumberEntry[] BuildLineNumberTable (LineNumberEntry[] line_numbers)
-               {
-                       ArrayList list = new ArrayList ();
-                       int last_offset = -1;
-                       int last_row = -1;
-
-                       for (int i = 0; i < line_numbers.Length; i++) {
-                               LineNumberEntry line = (LineNumberEntry) line_numbers [i];
-
-                               if (line.Offset > last_offset) {
-                                       if (last_row >= 0)
-                                               list.Add (new LineNumberEntry (last_row, last_offset));
-                                       last_row = line.Row;
-                                       last_offset = line.Offset;
-                               } else if (line.Row > last_row) {
-                                       last_row = line.Row;
-                               }
-                       }
-
-                       if (last_row >= 0)
-                               list.Add (new LineNumberEntry (last_row, last_offset));
-
-                       LineNumberEntry[] retval = new LineNumberEntry [list.Count];
-                       list.CopyTo (retval, 0);
-                       return retval;
-               }
-
                internal MethodSourceEntry Write (MonoSymbolFile file, BinaryWriter bw)
                {
                        NameOffset = (int) bw.BaseStream.Position;
@@ -608,18 +680,18 @@ namespace Mono.CSharp.Debugger
                                bw.Write (LocalTypeIndices [i]);
 
                        LocalVariableTableOffset = (int) bw.BaseStream.Position;
-
                        for (int i = 0; i < NumLocals; i++)
                                Locals [i].Write (file, bw);
+                       file.LocalCount += NumLocals;
 
                        LineNumberTableOffset = (int) bw.BaseStream.Position;
-
                        for (int i = 0; i < NumLineNumbers; i++)
                                LineNumbers [i].Write (bw);
-
                        file.LineNumberCount += NumLineNumbers;
-                       file.LocalCount += NumLocals;
 
+                       LexicalBlockTableOffset = (int) bw.BaseStream.Position;
+                       for (int i = 0; i < NumLexicalBlocks; i++)
+                               LexicalBlocks [i].Write (bw);
                        file_offset = (int) bw.BaseStream.Position;
 
                        index_entry = new MethodIndexEntry (file_offset, FullNameOffset, Token);
@@ -637,9 +709,12 @@ namespace Mono.CSharp.Debugger
                        bw.Write (TypeIndexTableOffset);
                        bw.Write (LocalVariableTableOffset);
                        bw.Write (LineNumberTableOffset);
+                       bw.Write (NumLexicalBlocks);
+                       bw.Write (LexicalBlockTableOffset);
                        bw.Write (NamespaceID);
+                       bw.Write (LocalNamesAmbiguous ? 1 : 0);
 
-                       return new MethodSourceEntry (index, file_offset, StartRow, EndRow);
+                       return new MethodSourceEntry (Index, file_offset, StartRow, EndRow);
                }
 
                internal void WriteIndex (BinaryWriter bw)
@@ -650,7 +725,7 @@ namespace Mono.CSharp.Debugger
                public override string ToString ()
                {
                        return String.Format ("[Method {0}:{1}:{2}:{3}:{4} - {7}:{8}:{9}:{10} - {5} - {6}]",
-                                             index, Token, SourceFileIndex, StartRow, EndRow,
+                                             Index, Token, SourceFileIndex, StartRow, EndRow,
                                              SourceFile, FullName, ClassTypeIndex, NumParameters,
                                              NumLocals, NumLineNumbers);
                }