diff options
author | David Karlaš <david.karlas@xamarin.com> | 2015-01-20 16:30:22 +0300 |
---|---|---|
committer | David Karlaš <david.karlas@xamarin.com> | 2015-01-27 15:37:52 +0300 |
commit | 463b45e3a33bf8d1b8fe64eac24dc4d7b82cd909 (patch) | |
tree | 686b57786683ab7fe4db19c32679131c28bf80af | |
parent | 7944f512c91572ec6af9d2b0c9aff2d06051cefd (diff) |
Sync Mono.CompilerServices.SymbolWriter with upstream for Column supportmono-3.0
6 files changed, 361 insertions, 375 deletions
diff --git a/symbols/mdb/Mono.Cecil.Mdb.csproj b/symbols/mdb/Mono.Cecil.Mdb.csproj index 44c931e..ab37a5e 100644 --- a/symbols/mdb/Mono.Cecil.Mdb.csproj +++ b/symbols/mdb/Mono.Cecil.Mdb.csproj @@ -90,6 +90,7 @@ <Compile Include="Mono.CompilerServices.SymbolWriter\MonoSymbolFile.cs" /> <Compile Include="Mono.CompilerServices.SymbolWriter\MonoSymbolTable.cs" /> <Compile Include="Mono.CompilerServices.SymbolWriter\MonoSymbolWriter.cs" /> + <Compile Include="Mono.CompilerServices.SymbolWriter\SourceMethodBuilder.cs" /> <Compile Include="Mono.CompilerServices.SymbolWriter\SymbolWriterImpl.cs" /> </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> diff --git a/symbols/mdb/Mono.Cecil.Mdb/MdbReader.cs b/symbols/mdb/Mono.Cecil.Mdb/MdbReader.cs index 9f3bf0c..b1c5cee 100644 --- a/symbols/mdb/Mono.Cecil.Mdb/MdbReader.cs +++ b/symbols/mdb/Mono.Cecil.Mdb/MdbReader.cs @@ -40,7 +40,7 @@ namespace Mono.Cecil.Mdb { public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName) { - return new MdbReader (MonoSymbolFile.ReadSymbolFile (module, fileName)); + return new MdbReader (MonoSymbolFile.ReadSymbolFile (fileName + ".mdb", module.Mvid)); } public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream) diff --git a/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs b/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs index 6ad39d2..73e654d 100644 --- a/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs +++ b/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs @@ -1,12 +1,13 @@ // -// Mono.CSharp.Debugger/MonoSymbolFile.cs +// MonoSymbolFile.cs // -// Author: +// Authors: // Martin Baulig (martin@ximian.com) +// Marek Safar (marek.safar@gmail.com) // // (C) 2003 Ximian, Inc. http://www.ximian.com +// Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com) // - // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -30,10 +31,7 @@ using System; using System.Reflection; -using SRE = System.Reflection.Emit; using System.Collections.Generic; -using System.Text; -using System.Threading; using System.IO; namespace Mono.CompilerServices.SymbolWriter @@ -46,10 +44,16 @@ namespace Mono.CompilerServices.SymbolWriter public MonoSymbolFileException (string message, params object[] args) : base (String.Format (message, args)) - { } + { + } + + public MonoSymbolFileException (string message, Exception innerException) + : base (message, innerException) + { + } } - internal class MyBinaryWriter : BinaryWriter + sealed class MyBinaryWriter : BinaryWriter { public MyBinaryWriter (Stream stream) : base (stream) @@ -109,64 +113,11 @@ namespace Mono.CompilerServices.SymbolWriter } } -#if !CECIL - internal class MonoDebuggerSupport - { - static GetMethodTokenFunc get_method_token; - static GetGuidFunc get_guid; - static GetLocalIndexFunc get_local_index; - - delegate int GetMethodTokenFunc (MethodBase method); - delegate Guid GetGuidFunc (Module module); - delegate int GetLocalIndexFunc (SRE.LocalBuilder local); - - static Delegate create_delegate (Type type, Type delegate_type, string name) - { - MethodInfo mi = type.GetMethod (name, BindingFlags.Static | - BindingFlags.NonPublic); - if (mi == null) - throw new Exception ("Can't find " + name); - - return Delegate.CreateDelegate (delegate_type, mi); - } - - static MonoDebuggerSupport () - { - get_method_token = (GetMethodTokenFunc) create_delegate ( - typeof (Assembly), typeof (GetMethodTokenFunc), - "MonoDebugger_GetMethodToken"); - - get_guid = (GetGuidFunc) create_delegate ( - typeof (Module), typeof (GetGuidFunc), "Mono_GetGuid"); - - get_local_index = (GetLocalIndexFunc) create_delegate ( - typeof (SRE.LocalBuilder), typeof (GetLocalIndexFunc), - "Mono_GetLocalIndex"); - } - - public static int GetMethodToken (MethodBase method) - { - return get_method_token (method); - } - - public static Guid GetGuid (Module module) - { - return get_guid (module); - } - - public static int GetLocalIndex (SRE.LocalBuilder local) - { - return get_local_index (local); - } - } -#endif - public class MonoSymbolFile : IDisposable { List<MethodEntry> methods = new List<MethodEntry> (); List<SourceFileEntry> sources = new List<SourceFileEntry> (); List<CompileUnitEntry> comp_units = new List<CompileUnitEntry> (); - Dictionary<Type, int> type_hash = new Dictionary<Type, int> (); Dictionary<int, AnonymousScopeEntry> anonymous_scopes; OffsetTable ot; @@ -174,41 +125,29 @@ namespace Mono.CompilerServices.SymbolWriter int last_method_index; int last_namespace_index; - public readonly string FileName = "<dynamic>"; public readonly int MajorVersion = OffsetTable.MajorVersion; public readonly int MinorVersion = OffsetTable.MinorVersion; public int NumLineNumbers; - internal MonoSymbolFile () + public MonoSymbolFile () { ot = new OffsetTable (); } - internal int AddSource (SourceFileEntry source) + public int AddSource (SourceFileEntry source) { sources.Add (source); return sources.Count; } - internal int AddCompileUnit (CompileUnitEntry entry) + public int AddCompileUnit (CompileUnitEntry entry) { comp_units.Add (entry); return comp_units.Count; } - internal int DefineType (Type type) - { - int index; - if (type_hash.TryGetValue (type, out index)) - return index; - - index = ++last_type_index; - type_hash.Add (type, index); - return index; - } - - internal void AddMethod (MethodEntry entry) + public void AddMethod (MethodEntry entry) { methods.Add (entry); } @@ -295,7 +234,7 @@ namespace Mono.CompilerServices.SymbolWriter // methods.Sort (); for (int i = 0; i < methods.Count; i++) - ((MethodEntry) methods [i]).Index = i + 1; + methods [i].Index = i + 1; // // Write data sections. @@ -314,7 +253,7 @@ namespace Mono.CompilerServices.SymbolWriter // ot.MethodTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < methods.Count; i++) { - MethodEntry entry = (MethodEntry) methods [i]; + MethodEntry entry = methods [i]; entry.Write (bw); } ot.MethodTableSize = (int) bw.BaseStream.Position - ot.MethodTableOffset; @@ -324,7 +263,7 @@ namespace Mono.CompilerServices.SymbolWriter // ot.SourceTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < sources.Count; i++) { - SourceFileEntry source = (SourceFileEntry) sources [i]; + SourceFileEntry source = sources [i]; source.Write (bw); } ot.SourceTableSize = (int) bw.BaseStream.Position - ot.SourceTableOffset; @@ -334,7 +273,7 @@ namespace Mono.CompilerServices.SymbolWriter // ot.CompileUnitTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < comp_units.Count; i++) { - CompileUnitEntry unit = (CompileUnitEntry) comp_units [i]; + CompileUnitEntry unit = comp_units [i]; unit.Write (bw); } ot.CompileUnitTableSize = (int) bw.BaseStream.Position - ot.CompileUnitTableOffset; @@ -391,10 +330,8 @@ namespace Mono.CompilerServices.SymbolWriter Guid guid; - MonoSymbolFile (string filename) + MonoSymbolFile (Stream stream) { - this.FileName = filename; - FileStream stream = new FileStream (filename, FileMode.Open, FileAccess.Read); reader = new MyBinaryReader (stream); try { @@ -403,94 +340,56 @@ namespace Mono.CompilerServices.SymbolWriter int minor_version = reader.ReadInt32 (); if (magic != OffsetTable.Magic) - throw new MonoSymbolFileException ( - "Symbol file `{0}' is not a valid " + - "Mono symbol file", filename); + throw new MonoSymbolFileException ("Symbol file is not a valid"); if (major_version != OffsetTable.MajorVersion) throw new MonoSymbolFileException ( - "Symbol file `{0}' has version {1}, " + - "but expected {2}", filename, major_version, - OffsetTable.MajorVersion); + "Symbol file has version {0} but expected {1}", major_version, OffsetTable.MajorVersion); if (minor_version != OffsetTable.MinorVersion) - throw new MonoSymbolFileException ( - "Symbol file `{0}' has version {1}.{2}, " + - "but expected {3}.{4}", filename, major_version, - minor_version, OffsetTable.MajorVersion, - OffsetTable.MinorVersion); + throw new MonoSymbolFileException ("Symbol file has version {0}.{1} but expected {2}.{3}", + major_version, minor_version, + OffsetTable.MajorVersion, OffsetTable.MinorVersion); MajorVersion = major_version; MinorVersion = minor_version; guid = new Guid (reader.ReadBytes (16)); ot = new OffsetTable (reader, major_version, minor_version); - } catch { - throw new MonoSymbolFileException ( - "Cannot read symbol file `{0}'", filename); + } catch (Exception e) { + throw new MonoSymbolFileException ("Cannot read symbol file", e); } source_file_hash = new Dictionary<int, SourceFileEntry> (); compile_unit_hash = new Dictionary<int, CompileUnitEntry> (); } - void CheckGuidMatch (Guid other, string filename, string assembly) + public static MonoSymbolFile ReadSymbolFile (Assembly assembly) { - if (other == guid) - return; - - throw new MonoSymbolFileException ( - "Symbol file `{0}' does not match assembly `{1}'", - filename, assembly); - } + string filename = assembly.Location; + string name = filename + ".mdb"; -#if CECIL - protected MonoSymbolFile (string filename, Mono.Cecil.ModuleDefinition module) - : this (filename) - { - // Check that the MDB file matches the module, if we have been - // passed a module. - if (module == null) - return; + Module[] modules = assembly.GetModules (); + Guid assembly_guid = modules[0].ModuleVersionId; - CheckGuidMatch (module.Mvid, filename, module.FullyQualifiedName); + return ReadSymbolFile (name, assembly_guid); } - public static MonoSymbolFile ReadSymbolFile (Mono.Cecil.ModuleDefinition module) - { - return ReadSymbolFile (module, module.FullyQualifiedName); - } - - public static MonoSymbolFile ReadSymbolFile (Mono.Cecil.ModuleDefinition module, string filename) - { - string name = filename + ".mdb"; - - return new MonoSymbolFile (name, module); - } -#else - protected MonoSymbolFile (string filename, Assembly assembly) : this (filename) + public static MonoSymbolFile ReadSymbolFile (string mdbFilename) { - // Check that the MDB file matches the assembly, if we have been - // passed an assembly. - if (assembly == null) - return; - - Module[] modules = assembly.GetModules (); - Guid assembly_guid = MonoDebuggerSupport.GetGuid (modules [0]); - - CheckGuidMatch (assembly_guid, filename, assembly.Location); + return ReadSymbolFile (new FileStream (mdbFilename, FileMode.Open, FileAccess.Read)); } - public static MonoSymbolFile ReadSymbolFile (Assembly assembly) + public static MonoSymbolFile ReadSymbolFile (string mdbFilename, Guid assemblyGuid) { - string filename = assembly.Location; - string name = filename + ".mdb"; + var sf = ReadSymbolFile (mdbFilename); + if (assemblyGuid != sf.guid) + throw new MonoSymbolFileException ("Symbol file `{0}' does not match assembly", mdbFilename); - return new MonoSymbolFile (name, assembly); + return sf; } -#endif - public static MonoSymbolFile ReadSymbolFile (string mdbFilename) + public static MonoSymbolFile ReadSymbolFile (Stream stream) { - return new MonoSymbolFile (mdbFilename); + return new MonoSymbolFile (stream); } public int CompileUnitCount { @@ -648,7 +547,7 @@ namespace Mono.CompilerServices.SymbolWriter lock (this) { read_methods (); - return (MethodEntry) method_list [index - 1]; + return method_list [index - 1]; } } diff --git a/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs b/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs index c170150..cf5d819 100644 --- a/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs +++ b/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs @@ -183,57 +183,56 @@ namespace Mono.CompilerServices.SymbolWriter { #region This is actually written to the symbol file public readonly int Row; + public int Column; + public int EndRow, EndColumn; public readonly int File; public readonly int Offset; - public readonly bool IsHidden; + public readonly bool IsHidden; // Obsolete is never used #endregion - public LineNumberEntry (int file, int row, int offset) - : this (file, row, offset, false) - { } - - public LineNumberEntry (int file, int row, int offset, bool is_hidden) + public sealed class LocationComparer : IComparer<LineNumberEntry> { - this.File = file; - this.Row = row; - this.Offset = offset; - this.IsHidden = is_hidden; - } - - public static LineNumberEntry Null = new LineNumberEntry (0, 0, 0); + public static readonly LocationComparer Default = new LocationComparer (); - private class OffsetComparerClass : IComparer<LineNumberEntry> - { public int Compare (LineNumberEntry l1, LineNumberEntry l2) { - if (l1.Offset < l2.Offset) - return -1; - else if (l1.Offset > l2.Offset) - return 1; - else - return 0; + return l1.Row == l2.Row ? + l1.Column.CompareTo (l2.Column) : + l1.Row.CompareTo (l2.Row); } } - private class RowComparerClass : IComparer<LineNumberEntry> + public static readonly LineNumberEntry Null = new LineNumberEntry (0, 0, 0, 0); + + public LineNumberEntry (int file, int row, int column, int offset) + : this (file, row, offset, column, false) + { + } + + public LineNumberEntry (int file, int row, int offset) + : this (file, row, -1, offset, false) { - public int Compare (LineNumberEntry l1, LineNumberEntry l2) - { - if (l1.Row < l2.Row) - return -1; - else if (l1.Row > l2.Row) - return 1; - else - return 0; - } } - public static readonly IComparer<LineNumberEntry> OffsetComparer = new OffsetComparerClass (); - public static readonly IComparer<LineNumberEntry> RowComparer = new RowComparerClass (); + public LineNumberEntry (int file, int row, int column, int offset, bool is_hidden) + : this (file, row, column, -1, -1, offset, is_hidden) + { + } + + public LineNumberEntry (int file, int row, int column, int end_row, int end_column, int offset, bool is_hidden) + { + this.File = file; + this.Row = row; + this.Column = column; + this.EndRow = end_row; + this.EndColumn = end_column; + this.Offset = offset; + this.IsHidden = is_hidden; + } public override string ToString () { - return String.Format ("[Line {0}:{1}:{2}]", File, Row, Offset); + return String.Format ("[Line {0}:{1,2}-{3,4}:{5}]", File, Row, Column, EndRow, EndColumn, Offset); } } @@ -610,6 +609,11 @@ namespace Mono.CompilerServices.SymbolWriter DataOffset = reader.ReadInt32 (); } + public void ReadAll () + { + ReadData (); + } + void ReadData () { if (creating) @@ -692,26 +696,33 @@ namespace Mono.CompilerServices.SymbolWriter creating = true; } - public SourceFileEntry (MonoSymbolFile file, string file_name, - byte[] guid, byte[] checksum) + public SourceFileEntry (MonoSymbolFile file, string file_name, byte[] guid, byte[] checksum) : this (file, file_name) { this.guid = guid; this.hash = checksum; } + public byte[] Checksum { + get { + return hash; + } + } + internal void WriteData (MyBinaryWriter bw) { DataOffset = (int) bw.BaseStream.Position; bw.Write (file_name); - if (guid == null) { - guid = Guid.NewGuid ().ToByteArray (); + if (guid == null) + guid = new byte[16]; + + if (hash == null) { try { - using (FileStream fs = new FileStream (file_name, FileMode.Open, FileAccess.Read)) { - MD5 md5 = MD5.Create (); - hash = md5.ComputeHash (fs); - } + using (FileStream fs = new FileStream (file_name, FileMode.Open, FileAccess.Read)) { + MD5 md5 = MD5.Create (); + hash = md5.ComputeHash (fs); + } } catch { hash = new byte [16]; } @@ -748,6 +759,7 @@ namespace Mono.CompilerServices.SymbolWriter public string FileName { get { return file_name; } + set { file_name = value; } } public bool AutoGenerated { @@ -802,7 +814,6 @@ namespace Mono.CompilerServices.SymbolWriter public const int Default_LineRange = 8; public const byte Default_OpcodeBase = 9; - public const bool SuppressDuplicates = true; #endregion public const byte DW_LNS_copy = 1; @@ -833,7 +844,7 @@ namespace Mono.CompilerServices.SymbolWriter this._line_numbers = lines; } - internal void Write (MonoSymbolFile file, MyBinaryWriter bw) + internal void Write (MonoSymbolFile file, MyBinaryWriter bw, bool hasColumnsInfo, bool hasEndInfo) { int start = (int) bw.BaseStream.Position; @@ -843,11 +854,6 @@ namespace Mono.CompilerServices.SymbolWriter int line_inc = LineNumbers [i].Row - last_line; int offset_inc = LineNumbers [i].Offset - last_offset; - if (SuppressDuplicates && (i+1 < LineNumbers.Length)) { - if (LineNumbers [i+1].Equals (LineNumbers [i])) - continue; - } - if (LineNumbers [i].File != last_file) { bw.Write (DW_LNS_set_file); bw.WriteLeb128 (LineNumbers [i].File); @@ -895,17 +901,37 @@ namespace Mono.CompilerServices.SymbolWriter bw.Write ((byte) 1); bw.Write (DW_LNE_end_sequence); + if (hasColumnsInfo) { + for (int i = 0; i < LineNumbers.Length; i++) { + var ln = LineNumbers [i]; + if (ln.Row >= 0) + bw.WriteLeb128 (ln.Column); + } + } + + if (hasEndInfo) { + for (int i = 0; i < LineNumbers.Length; i++) { + var ln = LineNumbers [i]; + if (ln.EndRow == -1 || ln.EndColumn == -1 || ln.Row > ln.EndRow) { + bw.WriteLeb128 (0xffffff); + } else { + bw.WriteLeb128 (ln.EndRow - ln.Row); + bw.WriteLeb128 (ln.EndColumn); + } + } + } + file.ExtendedLineNumberSize += (int) bw.BaseStream.Position - start; } - internal static LineNumberTable Read (MonoSymbolFile file, MyBinaryReader br) + internal static LineNumberTable Read (MonoSymbolFile file, MyBinaryReader br, bool readColumnsInfo, bool readEndInfo) { LineNumberTable lnt = new LineNumberTable (file); - lnt.DoRead (file, br); + lnt.DoRead (file, br, readColumnsInfo, readEndInfo); return lnt; } - void DoRead (MonoSymbolFile file, MyBinaryReader br) + void DoRead (MonoSymbolFile file, MyBinaryReader br, bool includesColumns, bool includesEnds) { var lines = new List<LineNumberEntry> (); @@ -922,7 +948,7 @@ namespace Mono.CompilerServices.SymbolWriter if (opcode == DW_LNE_end_sequence) { if (modified) lines.Add (new LineNumberEntry ( - stm_file, stm_line, stm_offset, is_hidden)); + stm_file, stm_line, -1, stm_offset, is_hidden)); break; } else if (opcode == DW_LNE_MONO_negate_is_hidden) { is_hidden = !is_hidden; @@ -931,9 +957,7 @@ namespace Mono.CompilerServices.SymbolWriter (opcode <= DW_LNE_MONO__extensions_end)) { ; // reserved for future extensions } else { - throw new MonoSymbolFileException ( - "Unknown extended opcode {0:x} in LNT ({1})", - opcode, file.FileName); + throw new MonoSymbolFileException ("Unknown extended opcode {0:x}", opcode); } br.BaseStream.Position = end_pos; @@ -942,7 +966,7 @@ namespace Mono.CompilerServices.SymbolWriter switch (opcode) { case DW_LNS_copy: lines.Add (new LineNumberEntry ( - stm_file, stm_line, stm_offset, is_hidden)); + stm_file, stm_line, -1, stm_offset, is_hidden)); modified = false; break; case DW_LNS_advance_pc: @@ -972,13 +996,34 @@ namespace Mono.CompilerServices.SymbolWriter stm_offset += opcode / LineRange; stm_line += LineBase + (opcode % LineRange); lines.Add (new LineNumberEntry ( - stm_file, stm_line, stm_offset, is_hidden)); + stm_file, stm_line, -1, stm_offset, is_hidden)); modified = false; } } - _line_numbers = new LineNumberEntry [lines.Count]; - lines.CopyTo (_line_numbers, 0); + _line_numbers = lines.ToArray (); + + if (includesColumns) { + for (int i = 0; i < _line_numbers.Length; ++i) { + var ln = _line_numbers[i]; + if (ln.Row >= 0) + ln.Column = br.ReadLeb128 (); + } + } + if (includesEnds) { + for (int i = 0; i < _line_numbers.Length; ++i) { + var ln = _line_numbers[i]; + + int row = br.ReadLeb128 (); + if (row == 0xffffff) { + ln.EndRow = -1; + ln.EndColumn = -1; + } else { + ln.EndRow = ln.Row + row; + ln.EndColumn = br.ReadLeb128 (); + } + } + } } public bool GetMethodBounds (out LineNumberEntry start, out LineNumberEntry end) @@ -1035,7 +1080,9 @@ namespace Mono.CompilerServices.SymbolWriter [Flags] public enum Flags { - LocalNamesAmbiguous = 1 + LocalNamesAmbiguous = 1, + ColumnsInfoIncluded = 1 << 1, + EndInfoIncluded = 1 << 2 } public const int Size = 12; @@ -1123,7 +1170,7 @@ namespace Mono.CompilerServices.SymbolWriter } } - void CheckLineNumberTable (LineNumberEntry[] line_numbers) + static void CheckLineNumberTable (LineNumberEntry[] line_numbers) { int last_offset = -1; int last_row = -1; @@ -1188,8 +1235,13 @@ namespace Mono.CompilerServices.SymbolWriter bw.Write (real_name); } + foreach (var lne in lnt.LineNumbers) { + if (lne.EndRow != -1 || lne.EndColumn != -1) + flags |= Flags.EndInfoIncluded; + } + LineNumberTableOffset = (int) bw.BaseStream.Position; - lnt.Write (file, bw); + lnt.Write (file, bw, (flags & Flags.ColumnsInfoIncluded) != 0, (flags & Flags.EndInfoIncluded) != 0); DataOffset = (int) bw.BaseStream.Position; @@ -1204,6 +1256,15 @@ namespace Mono.CompilerServices.SymbolWriter bw.WriteLeb128 ((int) flags); } + public void ReadAll () + { + GetLineNumberTable (); + GetLocals (); + GetCodeBlocks (); + GetScopeVariables (); + GetRealName (); + } + public LineNumberTable GetLineNumberTable () { lock (SymbolFile) { @@ -1217,7 +1278,7 @@ namespace Mono.CompilerServices.SymbolWriter long old_pos = reader.BaseStream.Position; reader.BaseStream.Position = LineNumberTableOffset; - lnt = LineNumberTable.Read (SymbolFile, reader); + lnt = LineNumberTable.Read (SymbolFile, reader, (flags & Flags.ColumnsInfoIncluded) != 0, (flags & Flags.EndInfoIncluded) != 0); reader.BaseStream.Position = old_pos; return lnt; diff --git a/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs b/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs index db77c25..19e14c2 100644 --- a/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs +++ b/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs @@ -47,11 +47,7 @@ namespace Mono.CompilerServices.SymbolWriter string filename; private SourceMethodBuilder current_method; -#if NET_2_1 - System.Collections.Stack current_method_stack = new System.Collections.Stack (); -#else Stack<SourceMethodBuilder> current_method_stack = new Stack<SourceMethodBuilder> (); -#endif public MonoSymbolWriter (string filename) { @@ -239,165 +235,4 @@ namespace Mono.CompilerServices.SymbolWriter } } } - - public class SourceMethodBuilder - { - List<LocalVariableEntry> _locals; - List<CodeBlockEntry> _blocks; - List<ScopeVariable> _scope_vars; -#if NET_2_1 - System.Collections.Stack _block_stack; -#else - Stack<CodeBlockEntry> _block_stack; -#endif - string _real_name; - IMethodDef _method; - ICompileUnit _comp_unit; -// MethodEntry.Flags _method_flags; - int _ns_id; - - public SourceMethodBuilder (ICompileUnit comp_unit, int ns_id, IMethodDef method) - { - this._comp_unit = comp_unit; - this._method = method; - this._ns_id = ns_id; - - method_lines = new LineNumberEntry [32]; - } - - private LineNumberEntry [] method_lines; - private int method_lines_pos = 0; - - public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, - bool is_hidden) - { - if (method_lines_pos == method_lines.Length) { - LineNumberEntry [] tmp = method_lines; - method_lines = new LineNumberEntry [method_lines.Length * 2]; - Array.Copy (tmp, method_lines, method_lines_pos); - } - - int file_idx = file != null ? file.Index : 0; - method_lines [method_lines_pos++] = new LineNumberEntry ( - file_idx, line, offset, is_hidden); - } - - public void StartBlock (CodeBlockEntry.Type type, int start_offset) - { - if (_block_stack == null) { -#if NET_2_1 - _block_stack = new System.Collections.Stack (); -#else - _block_stack = new Stack<CodeBlockEntry> (); -#endif - } - - if (_blocks == null) - _blocks = new List<CodeBlockEntry> (); - - int parent = CurrentBlock != null ? CurrentBlock.Index : -1; - - CodeBlockEntry block = new CodeBlockEntry ( - _blocks.Count + 1, parent, type, start_offset); - - _block_stack.Push (block); - _blocks.Add (block); - } - - public void EndBlock (int end_offset) - { - CodeBlockEntry block = (CodeBlockEntry) _block_stack.Pop (); - block.Close (end_offset); - } - - public CodeBlockEntry[] Blocks { - get { - if (_blocks == null) - return new CodeBlockEntry [0]; - - CodeBlockEntry[] retval = new CodeBlockEntry [_blocks.Count]; - _blocks.CopyTo (retval, 0); - return retval; - } - } - - public CodeBlockEntry CurrentBlock { - get { - if ((_block_stack != null) && (_block_stack.Count > 0)) - return (CodeBlockEntry) _block_stack.Peek (); - else - return null; - } - } - - public LocalVariableEntry[] Locals { - get { - if (_locals == null) - return new LocalVariableEntry [0]; - else { - LocalVariableEntry[] retval = - new LocalVariableEntry [_locals.Count]; - _locals.CopyTo (retval, 0); - return retval; - } - } - } - - public void AddLocal (int index, string name) - { - if (_locals == null) - _locals = new List<LocalVariableEntry> (); - int block_idx = CurrentBlock != null ? CurrentBlock.Index : 0; - _locals.Add (new LocalVariableEntry (index, name, block_idx)); - } - - public ScopeVariable[] ScopeVariables { - get { - if (_scope_vars == null) - return new ScopeVariable [0]; - - ScopeVariable[] retval = new ScopeVariable [_scope_vars.Count]; - _scope_vars.CopyTo (retval); - return retval; - } - } - - public void AddScopeVariable (int scope, int index) - { - if (_scope_vars == null) - _scope_vars = new List<ScopeVariable> (); - _scope_vars.Add ( - new ScopeVariable (scope, index)); - } - - public string RealMethodName { - get { return _real_name; } - } - - public void SetRealMethodName (string name) - { - _real_name = name; - } - - public ICompileUnit SourceFile { - get { return _comp_unit; } - } - - public IMethodDef Method { - get { return _method; } - } - - public void DefineMethod (MonoSymbolFile file) - { - LineNumberEntry[] lines = new LineNumberEntry [method_lines_pos]; - Array.Copy (method_lines, lines, method_lines_pos); - - MethodEntry entry = new MethodEntry ( - file, _comp_unit.Entry, _method.Token, ScopeVariables, - Locals, lines, Blocks, RealMethodName, 0, //_method_flags, - _ns_id); - - file.AddMethod (entry); - } - } } diff --git a/symbols/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs b/symbols/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs new file mode 100644 index 0000000..88363e7 --- /dev/null +++ b/symbols/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs @@ -0,0 +1,190 @@ +// +// SourceMethodBuilder.cs +// +// Authors: +// Martin Baulig (martin@ximian.com) +// Marek Safar (marek.safar@gmail.com) +// +// (C) 2002 Ximian, Inc. http://www.ximian.com +// Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System.Collections.Generic; + +namespace Mono.CompilerServices.SymbolWriter +{ + public class SourceMethodBuilder + { + List<LocalVariableEntry> _locals; + List<CodeBlockEntry> _blocks; + List<ScopeVariable> _scope_vars; + Stack<CodeBlockEntry> _block_stack; + readonly List<LineNumberEntry> method_lines; + + readonly ICompileUnit _comp_unit; + readonly int ns_id; + readonly IMethodDef method; + + public SourceMethodBuilder (ICompileUnit comp_unit) + { + this._comp_unit = comp_unit; + method_lines = new List<LineNumberEntry> (); + } + + public SourceMethodBuilder (ICompileUnit comp_unit, int ns_id, IMethodDef method) + : this (comp_unit) + { + this.ns_id = ns_id; + this.method = method; + } + + public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, bool is_hidden) + { + MarkSequencePoint (offset, file, line, column, -1, -1, is_hidden); + } + + public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, int end_line, int end_column, bool is_hidden) + { + int file_idx = file != null ? file.Index : 0; + var lne = new LineNumberEntry (file_idx, line, column, end_line, end_column, offset, is_hidden); + + if (method_lines.Count > 0) { + var prev = method_lines[method_lines.Count - 1]; + + // + // Same offset cannot be used for multiple lines + // + if (prev.Offset == offset) { + // + // Use the new location because debugger will adjust + // the breakpoint to next line with sequence point + // + if (LineNumberEntry.LocationComparer.Default.Compare (lne, prev) > 0) + method_lines[method_lines.Count - 1] = lne; + + return; + } + } + + method_lines.Add (lne); + } + + public void StartBlock (CodeBlockEntry.Type type, int start_offset) + { + if (_block_stack == null) { + _block_stack = new Stack<CodeBlockEntry> (); + } + + if (_blocks == null) + _blocks = new List<CodeBlockEntry> (); + + int parent = CurrentBlock != null ? CurrentBlock.Index : -1; + + CodeBlockEntry block = new CodeBlockEntry ( + _blocks.Count + 1, parent, type, start_offset); + + _block_stack.Push (block); + _blocks.Add (block); + } + + public void EndBlock (int end_offset) + { + CodeBlockEntry block = (CodeBlockEntry) _block_stack.Pop (); + block.Close (end_offset); + } + + public CodeBlockEntry[] Blocks { + get { + if (_blocks == null) + return new CodeBlockEntry [0]; + + CodeBlockEntry[] retval = new CodeBlockEntry [_blocks.Count]; + _blocks.CopyTo (retval, 0); + return retval; + } + } + + public CodeBlockEntry CurrentBlock { + get { + if ((_block_stack != null) && (_block_stack.Count > 0)) + return (CodeBlockEntry) _block_stack.Peek (); + else + return null; + } + } + + public LocalVariableEntry[] Locals { + get { + if (_locals == null) + return new LocalVariableEntry [0]; + else { + return _locals.ToArray (); + } + } + } + + public ICompileUnit SourceFile { + get { + return _comp_unit; + } + } + + public void AddLocal (int index, string name) + { + if (_locals == null) + _locals = new List<LocalVariableEntry> (); + int block_idx = CurrentBlock != null ? CurrentBlock.Index : 0; + _locals.Add (new LocalVariableEntry (index, name, block_idx)); + } + + public ScopeVariable[] ScopeVariables { + get { + if (_scope_vars == null) + return new ScopeVariable [0]; + + return _scope_vars.ToArray (); + } + } + + public void AddScopeVariable (int scope, int index) + { + if (_scope_vars == null) + _scope_vars = new List<ScopeVariable> (); + _scope_vars.Add ( + new ScopeVariable (scope, index)); + } + + public void DefineMethod (MonoSymbolFile file) + { + DefineMethod (file, method.Token); + } + + public void DefineMethod (MonoSymbolFile file, int token) + { + MethodEntry entry = new MethodEntry ( + file, _comp_unit.Entry, token, ScopeVariables, + Locals, method_lines.ToArray (), Blocks, null, MethodEntry.Flags.ColumnsInfoIncluded, ns_id); + + file.AddMethod (entry); + } + } +} |