public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, bool is_hidden) { int file_idx = file != null ? file.Index : 0; var lne = new LineNumberEntry (file_idx, line, 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 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]; }
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); }
public bool GetMethodBounds(out LineNumberEntry start, out LineNumberEntry end) { if (_line_numbers.Length > 1) { start = _line_numbers [0]; end = _line_numbers [_line_numbers.Length - 1]; return(true); } start = LineNumberEntry.Null; end = LineNumberEntry.Null; return(false); }
public void MarkSequencePoint(int offset, SourceFileEntry file, int start_line, int end_line, int start_col, int end_col) { 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, offset, start_line, end_line, start_col, end_col); }
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); }
internal MethodEntry(MonoSymbolFile file, CompileUnitEntry comp_unit, int token, ScopeVariable[] scope_vars, LocalVariableEntry[] locals, LineNumberEntry[] lines, CodeBlockEntry[] code_blocks, string real_name, MethodEntry.Flags flags, int namespace_id) { this.SymbolFile = file; this.real_name = real_name; this.locals = locals; this.code_blocks = code_blocks; this.scope_vars = scope_vars; this.flags = flags; this.index = -1; this.Token = token; this.CompileUnitIndex = comp_unit.Index; this.CompileUnit = comp_unit; this.NamespaceID = namespace_id; this.CheckLineNumberTable(lines); this.lnt = new LineNumberTable(file, lines); file.NumLineNumbers += lines.Length; int num_locals = (locals != null) ? locals.Length : 0; if (num_locals <= 32) { for (int i = 0; i < num_locals; i++) { string nm = locals[i].Name; for (int j = i + 1; j < num_locals; j++) { if (locals[j].Name == nm) { flags |= MethodEntry.Flags.LocalNamesAmbiguous; goto IL_108; } } } IL_108:; } else { Dictionary<string, LocalVariableEntry> local_names = new Dictionary<string, LocalVariableEntry>(); for (int k = 0; k < locals.Length; k++) { LocalVariableEntry local = locals[k]; if (local_names.ContainsKey(local.Name)) { flags |= MethodEntry.Flags.LocalNamesAmbiguous; break; } local_names.Add(local.Name, local); } } }
public bool GetMethodBounds(out LineNumberEntry start, out LineNumberEntry end) { bool result; if (this._line_numbers.Length > 1) { start = this._line_numbers[0]; end = this._line_numbers[this._line_numbers.Length - 1]; result = true; } else { start = LineNumberEntry.Null; end = LineNumberEntry.Null; result = false; } return(result); }
public int Compare(object a, object b) { LineNumberEntry l1 = (LineNumberEntry)a; LineNumberEntry l2 = (LineNumberEntry)b; if (l1.Row < l2.Row) { return(-1); } else if (l1.Row > l2.Row) { return(1); } else { return(0); } }
static void DumpLineNumberTable_internal(TextWriter writer, MonoSymbolFile file, Cecil.MethodDefinition mdef, C.MethodEntry entry) { string full_name = MonoSymbolFile.GetMethodName(mdef); if (mdef.MetadataToken.TokenType != Cecil.Metadata.TokenType.Method) { writer.WriteLine("UNKNOWN METHOD: {0}", full_name); return; } writer.WriteLine(); writer.WriteLine("Symfile Line Numbers (file / row / offset):"); writer.WriteLine("-------------------------------------------"); C.LineNumberEntry[] lnt; lnt = entry.GetLineNumberTable().LineNumbers; for (int i = 0; i < lnt.Length; i++) { C.LineNumberEntry lne = lnt [i]; writer.WriteLine("{0,4} {1,4} {2,4} {3,4:x}{4}", i, lne.File, lne.Row, lne.Offset, lne.IsHidden ? " (hidden)" : ""); } writer.WriteLine("-------------------------------------------"); writer.WriteLine(); List <string> lines; Dictionary <int, int> offsets; if (!DisassembleMethod_internal(file.ImageFile, (int)mdef.MetadataToken.RID, out lines, out offsets)) { writer.WriteLine("Cannot disassemble method: {0}", full_name); return; } writer.WriteLine("Disassembling {0}:\n\n{1}\n", full_name, String.Join("\n", lines.ToArray())); }
private void computeMethodCoverage (MethodCoverageItem method, LineNumberEntry[] lines, string cov_info) { ClassCoverageItem klass = method.Class; SourceFileCoverageData source = klass.sourceFile; source.AddMethod (method); int nlines = method.endLine - method.startLine + 1; int[] coverage = new int [nlines]; if (cov_info == null) { for (int i = 0; i < nlines; ++i) coverage [i] = 0; } else { for (int i = 0; i < nlines; ++i) coverage [i] = -1; // Hand crafted parsing code since this is performance critical int pos = 0; int prev_offset = 0; while (pos < cov_info.Length) { int pos2 = cov_info.IndexOfAny (digits, pos); if (pos2 == -1) break; pos = cov_info.IndexOfAny (ws, pos2); if (pos == -1) break; int offset = parsePositiveInteger (cov_info, pos2); pos2 = cov_info.IndexOfAny (digits, pos); if (pos2 == -1) break; pos = cov_info.IndexOfAny (ws, pos2); int count = parsePositiveInteger (cov_info, pos2); offset += prev_offset; prev_offset = offset; int line1 = 0; int line2 = 0; bool found = GetSourceRangeFor (offset, method, lines, ref line1, ref line2); /* if (found && (entry.Name.IndexOf ("Find") != -1)) { Console.WriteLine ("OFFSET: " + offset + " " + line1 + ":" + line2); } */ if (found) { for (int i = line1; i < line2 + 1; ++i) if ((i >= method.startLine) && (i <= method.endLine)) if (coverage [i - method.startLine] < count) coverage [i - method.startLine] = count; } } } int hit = 0; int missed = 0; for (int i = 0; i < nlines; ++i) { int count = coverage [i]; if (count > 0) hit ++; else if (count == 0) missed ++; } method.setCoverage (hit, missed); method.lineCoverage = coverage; }
public MethodEntry DefineMethod (CompileUnitEntry comp_unit, int token, ScopeVariable[] scope_vars, LocalVariableEntry[] locals, LineNumberEntry[] lines, CodeBlockEntry[] code_blocks, string real_name, MethodEntry.Flags flags, int namespace_id) { if (reader != null) throw new InvalidOperationException (); MethodEntry method = new MethodEntry ( this, comp_unit, token, scope_vars, locals, lines, code_blocks, real_name, flags, namespace_id); AddMethod (method); return method; }
public void Write (MonoSymbolWriter writer) { LineNumberEntry[] the_lines = new LineNumberEntry [lines.Count]; lines.CopyTo (the_lines, 0); LocalVariableEntry[] locals = method.GetLocalVars (); MethodEntry entry = writer.SymbolFile.DefineMethod ( file, Token, null, locals, the_lines, null, null, 0, 0); }
public bool GetMethodBounds (out LineNumberEntry start, out LineNumberEntry end) { if (_line_numbers.Length > 1) { start = _line_numbers [0]; end = _line_numbers [_line_numbers.Length - 1]; return true; } start = LineNumberEntry.Null; end = LineNumberEntry.Null; return false; }
internal LineNumberTable (MonoSymbolFile file, LineNumberEntry[] lines) : this (file) { this._line_numbers = lines; }
static SequencePoint LineToSequencePoint(LineNumberEntry line, MethodEntry entry, Document document) { return new SequencePoint (document) { StartLine = line.Row, EndLine = line.EndRow, StartColumn = line.Column, EndColumn = line.EndColumn, }; }
public void DefineMethod(MonoSymbolFile file) { LineNumberEntry[] lines = new LineNumberEntry[this.method_lines_pos]; Array.Copy(this.method_lines, lines, this.method_lines_pos); MethodEntry entry = new MethodEntry(file, this._comp_unit.Entry, this._method.Token, this.ScopeVariables, this.Locals, lines, this.Blocks, this.RealMethodName, (MethodEntry.Flags)0, this._ns_id); file.AddMethod(entry); }
public bool GetMethodBounds(out LineNumberEntry start, out LineNumberEntry end) { bool result; if (this._line_numbers.Length > 1) { start = this._line_numbers[0]; end = this._line_numbers[this._line_numbers.Length - 1]; result = true; } else { start = LineNumberEntry.Null; end = LineNumberEntry.Null; result = false; } return result; }
public bool GetMethodBounds(out LineNumberEntry start, out LineNumberEntry end) { start = end = LineNumberEntry.Null; bool have_start = false; foreach (LineNumberEntry entry in _line_numbers) { if (entry.IsHidden) continue; if (!have_start) { start = end = entry; have_start = true; } if (entry.Row > end.Row) end = entry; } if (!have_start || (start.File != end.File)) return false; return true; }
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 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 [50]; }
SequencePoint LineToSequencePoint(LineNumberEntry line) { var source = symbol_file.GetSourceFile (line.File); return new SequencePoint (line.Offset, GetDocument (source)) { StartLine = line.Row, EndLine = line.EndRow, StartColumn = line.Column, EndColumn = line.EndColumn, }; }
// // Return a range of source lines which have something to do with OFFSET. // private bool GetSourceRangeFor (int offset, MethodCoverageItem method, LineNumberEntry[] lines, ref int startLine, ref int endLine) { for (int i = 0; i < lines.Length; ++i) { if (offset >= lines [i].Offset) if (i == lines.Length - 1) { startLine = lines [i].Row; endLine = lines [i].Row; return true; } else if (offset < lines [i + 1].Offset) { startLine = lines [i].Row; endLine = lines [i + 1].Row - 1; return true; } } if (offset <= lines [0].Offset) { return false; } else { for (int i = 0; i < lines.Length; ++i) Console.WriteLine (lines [i]); throw new Exception ("Unable to determine source range for offset " + offset + " in " + method.name); } }
internal MethodEntry (MonoSymbolFile file, CompileUnitEntry comp_unit, int token, ScopeVariable[] scope_vars, LocalVariableEntry[] locals, LineNumberEntry[] lines, CodeBlockEntry[] code_blocks, string real_name, Flags flags, int namespace_id) { this.SymbolFile = file; this.real_name = real_name; this.locals = locals; this.code_blocks = code_blocks; this.scope_vars = scope_vars; this.flags = flags; index = -1; Token = token; CompileUnitIndex = comp_unit.Index; CompileUnit = comp_unit; NamespaceID = namespace_id; CheckLineNumberTable (lines); lnt = new LineNumberTable (file, lines); file.NumLineNumbers += lines.Length; int num_locals = locals != null ? locals.Length : 0; if (num_locals <= 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 < num_locals; i ++) { string nm = locals [i].Name; for (int j = i + 1; j < num_locals; j ++) { if (locals [j].Name == nm) { flags |= Flags.LocalNamesAmbiguous; goto locals_check_done; } } } locals_check_done : ; } else { Hashtable local_names = new Hashtable (); foreach (LocalVariableEntry local in locals) { if (local_names.Contains (local.Name)) { flags |= Flags.LocalNamesAmbiguous; break; } local_names.Add (local.Name, local); } } }
void CheckLineNumberTable (LineNumberEntry[] line_numbers) { int last_offset = -1; int last_row = -1; if (line_numbers == null) return; for (int i = 0; i < line_numbers.Length; i++) { LineNumberEntry line = line_numbers [i]; if (line.Equals (LineNumberEntry.Null)) throw new MonoSymbolFileException (); if (line.Offset < last_offset) throw new MonoSymbolFileException (); if (line.Offset > last_offset) { last_row = line.Row; last_offset = line.Offset; } else if (line.Row > last_row) { last_row = line.Row; } } }
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, _method_flags, _ns_id); file.AddMethod (entry); }
public void MarkSequencePoint(int offset, SourceFileEntry file, int start_line, int end_line, int start_col, int end_col) { 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, offset, start_line, end_line, start_col, end_col); }