📄 monosymboltable.cs
字号:
} public struct MethodSourceEntry : IComparable { #region This is actually written to the symbol file public readonly int Index; public readonly int FileOffset; public readonly int StartRow; public readonly int EndRow; #endregion public MethodSourceEntry (int index, int file_offset, int start, int end) { this.Index = index; this.FileOffset = file_offset; this.StartRow = start; this.EndRow = end; } internal MethodSourceEntry (BinaryReader reader) { Index = reader.ReadInt32 (); FileOffset = reader.ReadInt32 (); StartRow = reader.ReadInt32 (); EndRow = reader.ReadInt32 (); } public static int Size { get { return 16; } } internal void Write (BinaryWriter bw) { bw.Write (Index); bw.Write (FileOffset); bw.Write (StartRow); bw.Write (EndRow); } public int CompareTo (object obj) { MethodSourceEntry method = (MethodSourceEntry) obj; if (method.StartRow < StartRow) return -1; else if (method.StartRow > StartRow) return 1; else return 0; } public override string ToString () { return String.Format ("MethodSourceEntry ({0}:{1}:{2}:{3})", Index, FileOffset, StartRow, EndRow); } } public struct MethodIndexEntry { #region This is actually written to the symbol file public readonly int FileOffset; public readonly int Token; #endregion public static int Size { get { return 8; } } public MethodIndexEntry (int offset, int token) { this.FileOffset = offset; this.Token = token; } internal MethodIndexEntry (BinaryReader reader) { FileOffset = reader.ReadInt32 (); Token = reader.ReadInt32 (); } internal void Write (BinaryWriter bw) { bw.Write (FileOffset); bw.Write (Token); } public override string ToString () { return String.Format ("MethodIndexEntry ({0}:{1:x})", FileOffset, Token); } } 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 NumLocals; public readonly int NumLineNumbers; public readonly int NamespaceID; public readonly bool LocalNamesAmbiguous; int NameOffset; int TypeIndexTableOffset; int LocalVariableTableOffset; int LineNumberTableOffset; int NumLexicalBlocks; int LexicalBlockTableOffset; #endregion int index; int file_offset; public readonly SourceFileEntry SourceFile; public readonly LineNumberEntry[] LineNumbers; public readonly int[] LocalTypeIndices; public readonly LocalVariableEntry[] Locals; public readonly LexicalBlockEntry[] LexicalBlocks; public readonly MonoSymbolFile SymbolFile; public int Index { get { return index; } set { index = value; } } public static int Size { get { return 52; } } internal MethodEntry (MonoSymbolFile file, MyBinaryReader reader, int index) { this.SymbolFile = file; this.index = index; SourceFileIndex = reader.ReadInt32 (); Token = reader.ReadInt32 (); StartRow = reader.ReadInt32 (); EndRow = reader.ReadInt32 (); NumLocals = reader.ReadInt32 (); NumLineNumbers = reader.ReadInt32 (); NameOffset = reader.ReadInt32 (); TypeIndexTableOffset = reader.ReadInt32 (); LocalVariableTableOffset = reader.ReadInt32 (); LineNumberTableOffset = reader.ReadInt32 (); NumLexicalBlocks = reader.ReadInt32 (); LexicalBlockTableOffset = reader.ReadInt32 (); NamespaceID = reader.ReadInt32 (); LocalNamesAmbiguous = reader.ReadInt32 () != 0; SourceFile = file.GetSourceFile (SourceFileIndex); if (LineNumberTableOffset != 0) { long old_pos = reader.BaseStream.Position; reader.BaseStream.Position = LineNumberTableOffset; LineNumbers = new LineNumberEntry [NumLineNumbers]; for (int i = 0; i < NumLineNumbers; i++) LineNumbers [i] = new LineNumberEntry (reader); reader.BaseStream.Position = old_pos; } if (LocalVariableTableOffset != 0) { long old_pos = reader.BaseStream.Position; reader.BaseStream.Position = LocalVariableTableOffset; Locals = new LocalVariableEntry [NumLocals]; for (int i = 0; i < NumLocals; i++) Locals [i] = new LocalVariableEntry (reader); reader.BaseStream.Position = old_pos; } if (TypeIndexTableOffset != 0) { long old_pos = reader.BaseStream.Position; reader.BaseStream.Position = TypeIndexTableOffset; LocalTypeIndices = new int [NumLocals]; for (int i = 0; i < NumLocals; i++) LocalTypeIndices [i] = reader.ReadInt32 (); 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, string name, int token, LocalVariableEntry[] locals, LineNumberEntry[] lines, LexicalBlockEntry[] blocks, int start_row, int end_row, int namespace_id) { this.SymbolFile = file; index = -1; Token = token; SourceFileIndex = source.Index; SourceFile = source; StartRow = start_row; EndRow = end_row; NamespaceID = namespace_id; LexicalBlocks = blocks; NumLexicalBlocks = LexicalBlocks != null ? LexicalBlocks.Length : 0; LineNumbers = BuildLineNumberTable (lines); NumLineNumbers = LineNumbers.Length; file.NumLineNumbers += NumLineNumbers; NumLocals = locals != null ? locals.Length : 0; 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 (); } static LineNumberEntry [] tmp_buff = new LineNumberEntry [20]; // BuildLineNumberTable() eliminates duplicate line numbers and ensures // we aren't going "backwards" since this would counfuse the runtime's // debugging code (and the debugger). // // In the line number table, the "offset" field most be strictly // monotonic increasing; that is, the next entry must not have an offset // which is equal to or less than the current one. // // The most common case is that our input (ie. the line number table as // we get it from mcs) contains several entries with the same offset // (and different line numbers) - but it may also happen that the offset // is decreasing (this can be considered as an exception, such lines will // simply be discarded). LineNumberEntry[] BuildLineNumberTable (LineNumberEntry[] line_numbers) { 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]; for (int i = 0; i < line_numbers.Length; i++) { LineNumberEntry line = line_numbers [i]; if (line.Offset > last_offset) { if (last_row >= 0) tmp_buff [pos ++] = 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) tmp_buff [pos ++] = new LineNumberEntry (last_row, last_offset); LineNumberEntry [] retval = new LineNumberEntry [pos]; Array.Copy (tmp_buff, retval, pos); return retval; } internal MethodSourceEntry Write (MonoSymbolFile file, MyBinaryWriter bw) { if (index <= 0) throw new InvalidOperationException (); NameOffset = (int) bw.BaseStream.Position; TypeIndexTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < NumLocals; i++) 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; LexicalBlockTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < NumLexicalBlocks; i++) LexicalBlocks [i].Write (bw); file_offset = (int) bw.BaseStream.Position; bw.Write (SourceFileIndex); bw.Write (Token); bw.Write (StartRow); bw.Write (EndRow); bw.Write (NumLocals); bw.Write (NumLineNumbers); bw.Write (NameOffset); 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); } internal void WriteIndex (BinaryWriter bw) { 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} - {5}]", index, Token, SourceFileIndex, StartRow, EndRow, SourceFile, NumLocals, NumLineNumbers); } } public struct NamespaceEntry { #region This is actually written to the symbol file public readonly string Name; public readonly int Index; public readonly int Parent; public readonly string[] UsingClauses; #endregion public NamespaceEntry (string name, int index, string[] using_clauses, int parent) { this.Name = name; this.Index = index; this.Parent = parent; this.UsingClauses = using_clauses != null ? using_clauses : new string [0]; } internal NamespaceEntry (MonoSymbolFile file, MyBinaryReader reader) { Name = reader.ReadString (); Index = reader.ReadLeb128 (); Parent = reader.ReadLeb128 (); int count = reader.ReadLeb128 (); UsingClauses = new string [count]; for (int i = 0; i < count; i++) UsingClauses [i] = reader.ReadString (); } internal void Write (MonoSymbolFile file, MyBinaryWriter bw) { bw.Write (Name); bw.WriteLeb128 (Index); bw.WriteLeb128 (Parent); bw.WriteLeb128 (UsingClauses.Length); foreach (string uc in UsingClauses) bw.Write (uc); } public override string ToString () { return String.Format ("[Namespace {0}:{1}:{2}]", Name, Index, Parent); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -