2004-10-20 Martin Baulig <martin@ximian.com>
[mono.git] / mcs / class / Mono.CSharp.Debugger / MonoSymbolTable.cs
index 07a868160517a80a6a0f7ddb632838cb6604a1bd..4fadaf1e18b467e5411801c0d61b7bc920e55401 100644 (file)
@@ -1,5 +1,5 @@
 //
-// System.Diagnostics.SymbolStore/MonoSymbolTable.cs
+// Mono.CSharp.Debugger/MonoSymbolTable.cs
 //
 // Author:
 //   Martin Baulig (martin@ximian.com)
@@ -29,8 +29,6 @@
 //
 
 using System;
-using System.Reflection;
-using System.Reflection.Emit;
 using System.Collections;
 using System.Text;
 using System.IO;
@@ -69,11 +67,11 @@ using System.IO;
 // changing the file format.
 //
 
-namespace Mono.CSharp.Debugger
+namespace Mono.CompilerServices.SymbolWriter
 {
        public struct OffsetTable
        {
-               public const int  Version = 37;
+               public const int  Version = 38;
                public const long Magic   = 0x45e82623fd7fa614;
 
                #region This is actually written to the symbol file
@@ -209,7 +207,7 @@ namespace Mono.CSharp.Debugger
                        this.StartOffset = start_offset;
                }
 
-               internal LexicalBlockEntry (int index, BinaryReader reader)
+               internal LexicalBlockEntry (int index, MyBinaryReader reader)
                {
                        this.Index = index;
                        this.StartOffset = reader.ReadInt32 ();
@@ -221,7 +219,7 @@ namespace Mono.CSharp.Debugger
                        this.EndOffset = end_offset;
                }
 
-               internal void Write (BinaryWriter bw)
+               internal void Write (MyBinaryWriter bw)
                {
                        bw.Write (StartOffset);
                        bw.Write (EndOffset);
@@ -237,43 +235,36 @@ namespace Mono.CSharp.Debugger
        {
                #region This is actually written to the symbol file
                public readonly string Name;
-               public readonly FieldAttributes Attributes;
                public readonly byte[] Signature;
                public readonly int BlockIndex;
                #endregion
 
-               public LocalVariableEntry (string Name, FieldAttributes Attributes, byte[] Signature,
-                                          int BlockIndex)
+               public LocalVariableEntry (string Name, byte[] Signature, int BlockIndex)
                {
                        this.Name = Name;
-                       this.Attributes = Attributes;
                        this.Signature = Signature;
                        this.BlockIndex = BlockIndex;
                }
 
-               internal LocalVariableEntry (BinaryReader reader)
+               internal LocalVariableEntry (MyBinaryReader reader)
                {
-                       int name_length = reader.ReadInt32 ();
-                       byte[] name = reader.ReadBytes (name_length);
-                       Name = Encoding.UTF8.GetString (name);
-                       Attributes = (FieldAttributes) reader.ReadInt32 ();
-                       int sig_length = reader.ReadInt32 ();
+                       Name = reader.ReadString ();
+                       int sig_length = reader.ReadLeb128 ();
                        Signature = reader.ReadBytes (sig_length);
-                       BlockIndex = reader.ReadInt32 ();
+                       BlockIndex = reader.ReadLeb128 ();
                }
 
-               internal void Write (MonoSymbolFile file, BinaryWriter bw)
+               internal void Write (MonoSymbolFile file, MyBinaryWriter bw)
                {
-                       file.WriteString (bw, Name);
-                       bw.Write ((int) Attributes);
-                       bw.Write ((int) Signature.Length);
+                       bw.Write (Name);
+                       bw.WriteLeb128 ((int) Signature.Length);
                        bw.Write (Signature);
-                       bw.Write (BlockIndex);
+                       bw.WriteLeb128 (BlockIndex);
                }
 
                public override string ToString ()
                {
-                       return String.Format ("[LocalVariable {0}:{1}]", Name, Attributes);
+                       return String.Format ("[LocalVariable {0}]", Name);
                }
        }
 
@@ -298,7 +289,7 @@ namespace Mono.CSharp.Debugger
                        get { return 24; }
                }
 
-               internal SourceFileEntry (MonoSymbolFile file, string file_name)
+               public SourceFileEntry (MonoSymbolFile file, string file_name)
                {
                        this.file = file;
                        this.file_name = file_name;
@@ -309,7 +300,7 @@ namespace Mono.CSharp.Debugger
                        namespaces = new ArrayList ();
                }
 
-               public void DefineMethod (MethodBase method, int token, LocalVariableEntry[] locals,
+               public void DefineMethod (string name, int token, LocalVariableEntry[] locals,
                                          LineNumberEntry[] lines, LexicalBlockEntry[] blocks,
                                          int start, int end, int namespace_id)
                {
@@ -317,7 +308,8 @@ namespace Mono.CSharp.Debugger
                                throw new InvalidOperationException ();
 
                        MethodEntry entry = new MethodEntry (
-                               file, this, method, token, locals, lines, blocks, start, end, namespace_id);
+                               file, this, name, (int) token, locals, lines, blocks,
+                               start, end, namespace_id);
 
                        methods.Add (entry);
                        file.AddMethod (entry);
@@ -334,10 +326,10 @@ namespace Mono.CSharp.Debugger
                        return index;
                }
 
-               internal void WriteData (BinaryWriter bw)
+               internal void WriteData (MyBinaryWriter bw)
                {
                        NameOffset = (int) bw.BaseStream.Position;
-                       file.WriteString (bw, file_name);
+                       bw.Write (file_name);
 
                        ArrayList list = new ArrayList ();
                        foreach (MethodEntry entry in methods)
@@ -408,7 +400,7 @@ namespace Mono.CSharp.Debugger
                                if (creating)
                                        throw new InvalidOperationException ();
 
-                               BinaryReader reader = file.BinaryReader;
+                               MyBinaryReader reader = file.BinaryReader;
                                int old_pos = (int) reader.BaseStream.Position;
 
                                reader.BaseStream.Position = NamespaceTableOffset;
@@ -522,15 +514,13 @@ namespace Mono.CSharp.Debugger
                }
        }
 
-       public class MethodEntry
+       public class MethodEntry : IComparable
        {
                #region This is actually written to the symbol file
                public readonly int SourceFileIndex;
                public readonly int Token;
                public readonly int StartRow;
                public readonly int EndRow;
-               public readonly int ClassTypeIndex;
-               public readonly int NumParameters;
                public readonly int NumLocals;
                public readonly int NumLineNumbers;
                public readonly int NamespaceID;
@@ -544,42 +534,34 @@ namespace Mono.CSharp.Debugger
                int LexicalBlockTableOffset;
                #endregion
 
+               int index;
                int file_offset;
-               string name;
 
-               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;
 
-               public static int Size {
-                       get { return 52; }
-               }
-
-               public string Name {
-                       get { return name; }
+               public int Index {
+                       get { return index; }
+                       set { index = value; }
                }
 
-               public MethodBase MethodBase {
-                       get { return MonoDebuggerSupport.GetMethod (SymbolFile.Assembly, Token); }
+               public static int Size {
+                       get { return 52; }
                }
 
-               internal MethodEntry (MonoSymbolFile file, BinaryReader reader, int index)
+               internal MethodEntry (MonoSymbolFile file, MyBinaryReader reader, int index)
                {
                        this.SymbolFile = file;
-                       this.Index = index;
+                       this.index = index;
                        SourceFileIndex = reader.ReadInt32 ();
                        Token = reader.ReadInt32 ();
                        StartRow = reader.ReadInt32 ();
                        EndRow = reader.ReadInt32 ();
-                       ClassTypeIndex = reader.ReadInt32 ();
-                       NumParameters = reader.ReadInt32 ();
                        NumLocals = reader.ReadInt32 ();
                        NumLineNumbers = reader.ReadInt32 ();
                        NameOffset = reader.ReadInt32 ();
@@ -591,8 +573,6 @@ namespace Mono.CSharp.Debugger
                        NamespaceID = reader.ReadInt32 ();
                        LocalNamesAmbiguous = reader.ReadInt32 () != 0;
 
-                       name = file.ReadString (NameOffset);
-
                        SourceFile = file.GetSourceFile (SourceFileIndex);
 
                        if (LineNumberTableOffset != 0) {
@@ -612,15 +592,9 @@ namespace Mono.CSharp.Debugger
                                reader.BaseStream.Position = LocalVariableTableOffset;
 
                                Locals = new LocalVariableEntry [NumLocals];
-                               LocalTypes = new Type [NumLocals];
-
-                               Assembly ass = file.Assembly;
 
-                               for (int i = 0; i < NumLocals; i++) {
+                               for (int i = 0; i < NumLocals; i++)
                                        Locals [i] = new LocalVariableEntry (reader);
-                                       LocalTypes [i] = MonoDebuggerSupport.GetLocalTypeFromSignature (
-                                               ass, Locals [i].Signature);
-                               }
 
                                reader.BaseStream.Position = old_pos;
                        }
@@ -629,11 +603,8 @@ namespace Mono.CSharp.Debugger
                                long old_pos = reader.BaseStream.Position;
                                reader.BaseStream.Position = TypeIndexTableOffset;
 
-                               ParamTypeIndices = new int [NumParameters];
                                LocalTypeIndices = new int [NumLocals];
 
-                               for (int i = 0; i < NumParameters; i++)
-                                       ParamTypeIndices [i] = reader.ReadInt32 ();
                                for (int i = 0; i < NumLocals; i++)
                                        LocalTypeIndices [i] = reader.ReadInt32 ();
 
@@ -652,13 +623,14 @@ namespace Mono.CSharp.Debugger
                        }
                }
 
-               internal MethodEntry (MonoSymbolFile file, SourceFileEntry source, MethodBase method,
-                                     int token, LocalVariableEntry[] locals, LineNumberEntry[] lines,
-                                     LexicalBlockEntry[] blocks, int start_row, int end_row,
-                                     int namespace_id)
+               internal MethodEntry (MonoSymbolFile file, SourceFileEntry source,
+                                     string name, int token, LocalVariableEntry[] locals,
+                                     LineNumberEntry[] lines, LexicalBlockEntry[] blocks,
+                                     int start_row, int end_row, int namespace_id)
                {
                        this.SymbolFile = file;
-                       Index = file.GetNextMethodIndex ();
+
+                       index = -1;
 
                        Token = token;
                        SourceFileIndex = source.Index;
@@ -667,23 +639,14 @@ namespace Mono.CSharp.Debugger
                        EndRow = end_row;
                        NamespaceID = namespace_id;
                        LexicalBlocks = blocks;
-                       NumLexicalBlocks = LexicalBlocks.Length;
+                       NumLexicalBlocks = LexicalBlocks != null ? LexicalBlocks.Length : 0;
 
                        LineNumbers = BuildLineNumberTable (lines);
                        NumLineNumbers = LineNumbers.Length;
 
-                       ParameterInfo[] parameters = method.GetParameters ();
-                       if (parameters == null)
-                               parameters = new ParameterInfo [0];
-                       
-                       name = method.Name;
-                       
-                       NumParameters = parameters.Length;
-                       ParamTypeIndices = new int [NumParameters];
-                       for (int i = 0; i < NumParameters; i++)
-                               ParamTypeIndices [i] = file.DefineType (parameters [i].ParameterType);
+                       file.NumLineNumbers += NumLineNumbers;
 
-                       NumLocals = locals.Length;
+                       NumLocals = locals != null ? locals.Length : 0;
                        Locals = locals;
 
                        if (NumLocals <= 32) {
@@ -717,8 +680,6 @@ namespace Mono.CSharp.Debugger
                        LocalTypeIndices = new int [NumLocals];
                        for (int i = 0; i < NumLocals; i++)
                                LocalTypeIndices [i] = file.GetNextTypeIndex ();
-
-                       ClassTypeIndex = file.DefineType (method.ReflectedType);
                }
                
                static LineNumberEntry [] tmp_buff = new LineNumberEntry [20];
@@ -741,6 +702,9 @@ namespace Mono.CSharp.Debugger
                        int pos = 0;
                        int last_offset = -1;
                        int last_row = -1;
+
+                       if (line_numbers == null)
+                               return new LineNumberEntry [0];
                        
                        if (tmp_buff.Length < (line_numbers.Length + 1))
                                tmp_buff = new LineNumberEntry [(line_numbers.Length + 1) * 2];
@@ -766,15 +730,15 @@ namespace Mono.CSharp.Debugger
                        return retval;
                }
 
-               internal MethodSourceEntry Write (MonoSymbolFile file, BinaryWriter bw)
+               internal MethodSourceEntry Write (MonoSymbolFile file, MyBinaryWriter bw)
                {
+                       if (index <= 0)
+                               throw new InvalidOperationException ();
+
                        NameOffset = (int) bw.BaseStream.Position;
-                       file.WriteString (bw, name);
 
                        TypeIndexTableOffset = (int) bw.BaseStream.Position;
 
-                       for (int i = 0; i < NumParameters; i++)
-                               bw.Write (ParamTypeIndices [i]);
                        for (int i = 0; i < NumLocals; i++)
                                bw.Write (LocalTypeIndices [i]);
 
@@ -797,8 +761,6 @@ namespace Mono.CSharp.Debugger
                        bw.Write (Token);
                        bw.Write (StartRow);
                        bw.Write (EndRow);
-                       bw.Write (ClassTypeIndex);
-                       bw.Write (NumParameters);
                        bw.Write (NumLocals);
                        bw.Write (NumLineNumbers);
                        bw.Write (NameOffset);
@@ -810,7 +772,7 @@ namespace Mono.CSharp.Debugger
                        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)
@@ -818,12 +780,23 @@ namespace Mono.CSharp.Debugger
                        new MethodIndexEntry (file_offset, Token).Write (bw);
                }
 
+               public int CompareTo (object obj)
+               {
+                       MethodEntry method = (MethodEntry) obj;
+
+                       if (method.Token < Token)
+                               return 1;
+                       else if (method.Token > Token)
+                               return -1;
+                       else
+                               return 0;
+               }
+
                public override string ToString ()
                {
-                       return String.Format ("[Method {0}:{1}:{2}:{3}:{4} - {6}:{7}:{8}:{9} - {5}]",
-                                             Index, Token, SourceFileIndex, StartRow, EndRow,
-                                             SourceFile, ClassTypeIndex, NumParameters,
-                                             NumLocals, NumLineNumbers);
+                       return String.Format ("[Method {0}:{1}:{2}:{3}:{4} - {6}:{7} - {5}]",
+                                             index, Token, SourceFileIndex, StartRow, EndRow,
+                                             SourceFile, NumLocals, NumLineNumbers);
                }
        }
 
@@ -844,26 +817,26 @@ namespace Mono.CSharp.Debugger
                        this.UsingClauses = using_clauses != null ? using_clauses : new string [0];
                }
 
-               internal NamespaceEntry (MonoSymbolFile file, BinaryReader reader)
+               internal NamespaceEntry (MonoSymbolFile file, MyBinaryReader reader)
                {
-                       Name = file.ReadString ();
-                       Index = reader.ReadInt32 ();
-                       Parent = reader.ReadInt32 ();
+                       Name = reader.ReadString ();
+                       Index = reader.ReadLeb128 ();
+                       Parent = reader.ReadLeb128 ();
 
-                       int count = reader.ReadInt32 ();
+                       int count = reader.ReadLeb128 ();
                        UsingClauses = new string [count];
                        for (int i = 0; i < count; i++)
-                               UsingClauses [i] = file.ReadString ();
+                               UsingClauses [i] = reader.ReadString ();
                }
 
-               internal void Write (MonoSymbolFile file, BinaryWriter bw)
+               internal void Write (MonoSymbolFile file, MyBinaryWriter bw)
                {
-                       file.WriteString (bw, Name);
-                       bw.Write (Index);
-                       bw.Write (Parent);
-                       bw.Write (UsingClauses.Length);
+                       bw.Write (Name);
+                       bw.WriteLeb128 (Index);
+                       bw.WriteLeb128 (Parent);
+                       bw.WriteLeb128 (UsingClauses.Length);
                        foreach (string uc in UsingClauses)
-                               file.WriteString (bw, uc);
+                               bw.Write (uc);
                }
 
                public override string ToString ()