X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FMono.CompilerServices.SymbolWriter%2FMonoSymbolWriter.cs;h=b2c2afdba619bdf08b9f47c310f3cab2f15c99a6;hb=b59807ecfab572c43c53918d85d2ad2f8db17432;hp=7a38a2e10248935a1c0b0f7c3e0fcc39471b5621;hpb=da4f9e9b2afb23791029d0bb09d78b868aabd870;p=mono.git diff --git a/mcs/class/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs b/mcs/class/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs index 7a38a2e1024..b2c2afdba61 100644 --- a/mcs/class/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs +++ b/mcs/class/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs @@ -33,109 +33,99 @@ using System; using System.Runtime.CompilerServices; -using System.Collections; +using System.Collections.Generic; using System.IO; namespace Mono.CompilerServices.SymbolWriter { - public interface ISourceFile - { - SourceFileEntry Entry { - get; - } - } - - public interface ISourceMethod - { - string Name { - get; - } - - int NamespaceID { - get; - } - - int Token { - get; - } - } - public class MonoSymbolWriter { - protected ArrayList locals = null; - protected ArrayList methods = null; - protected ArrayList sources = null; + List methods; + List sources; + List comp_units; protected readonly MonoSymbolFile file; - private string filename = null; + string filename; - LineNumberEntry [] current_method_lines; - int current_method_lines_pos = 0; - - internal ISourceFile[] Sources { - get { - ISourceFile[] retval = new ISourceFile [sources.Count]; - sources.CopyTo (retval, 0); - return retval; - } - } - - private SourceMethod current_method = null; + private SourceMethodBuilder current_method; + Stack current_method_stack = new Stack (); public MonoSymbolWriter (string filename) { - this.methods = new ArrayList (); - this.sources = new ArrayList (); - this.locals = new ArrayList (); + this.methods = new List (); + this.sources = new List (); + this.comp_units = new List (); this.file = new MonoSymbolFile (); this.filename = filename + ".mdb"; - - this.current_method_lines = new LineNumberEntry [50]; + } + + public MonoSymbolFile SymbolFile { + get { return file; } } public void CloseNamespace () { } - public void DefineLocalVariable (int index, string name, byte[] signature) + public void DefineLocalVariable (int index, string name) { if (current_method == null) return; - current_method.AddLocal (index, name, signature); + current_method.AddLocal (index, name); + } + + public void DefineCapturedLocal (int scope_id, string name, string captured_name) + { + file.DefineCapturedVariable (scope_id, name, captured_name, + CapturedVariable.CapturedKind.Local); + } + + public void DefineCapturedParameter (int scope_id, string name, string captured_name) + { + file.DefineCapturedVariable (scope_id, name, captured_name, + CapturedVariable.CapturedKind.Parameter); + } + + public void DefineCapturedThis (int scope_id, string captured_name) + { + file.DefineCapturedVariable (scope_id, "this", captured_name, + CapturedVariable.CapturedKind.This); } - public void MarkSequencePoint (int offset, int line, int column) + public void DefineCapturedScope (int scope_id, int id, string captured_name) + { + file.DefineCapturedScope (scope_id, id, captured_name); + } + + public void DefineScopeVariable (int scope, int index) { if (current_method == null) return; - if (current_method_lines_pos == current_method_lines.Length) { - LineNumberEntry [] tmp = current_method_lines; - current_method_lines = new LineNumberEntry [current_method_lines.Length * 2]; - Array.Copy (tmp, current_method_lines, current_method_lines_pos); - } - - current_method_lines [current_method_lines_pos++] = new LineNumberEntry (line, offset); + current_method.AddScopeVariable (scope, index); } - public void OpenMethod (ISourceFile file, ISourceMethod method, - int startRow, int startColumn, - int endRow, int endColumn) + public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, + bool is_hidden) { - SourceMethod source = new SourceMethod ( - file, method, startRow, startColumn, endRow, endColumn); + if (current_method == null) + return; - current_method = source; + current_method.MarkSequencePoint (offset, file, line, column, is_hidden); + } + + public SourceMethodBuilder OpenMethod (ICompileUnit file, int ns_id, IMethodDef method) + { + SourceMethodBuilder builder = new SourceMethodBuilder (file, ns_id, method); + current_method_stack.Push (current_method); + current_method = builder; methods.Add (current_method); + return builder; } public void CloseMethod () { - current_method.SetLineNumbers ( - current_method_lines, current_method_lines_pos); - current_method_lines_pos = 0; - - current_method = null; + current_method = (SourceMethodBuilder) current_method_stack.Pop (); } public SourceFileEntry DefineDocument (string url) @@ -145,188 +135,103 @@ namespace Mono.CompilerServices.SymbolWriter return entry; } - public int DefineNamespace (string name, SourceFileEntry source, + public SourceFileEntry DefineDocument (string url, byte[] guid, byte[] checksum) + { + SourceFileEntry entry = new SourceFileEntry (file, url, guid, checksum); + sources.Add (entry); + return entry; + } + + public CompileUnitEntry DefineCompilationUnit (SourceFileEntry source) + { + CompileUnitEntry entry = new CompileUnitEntry (file, source); + comp_units.Add (entry); + return entry; + } + + public int DefineNamespace (string name, CompileUnitEntry unit, string[] using_clauses, int parent) { - if ((source == null) || (using_clauses == null)) + if ((unit == null) || (using_clauses == null)) throw new NullReferenceException (); - return source.DefineNamespace (name, using_clauses, parent); + return unit.DefineNamespace (name, using_clauses, parent); } - public int OpenScope (int startOffset) + public int OpenScope (int start_offset) { if (current_method == null) return 0; - current_method.StartBlock (startOffset); + current_method.StartBlock (CodeBlockEntry.Type.Lexical, start_offset); return 0; } - public void CloseScope (int endOffset) + public void CloseScope (int end_offset) { if (current_method == null) return; - current_method.EndBlock (endOffset); + current_method.EndBlock (end_offset); } - public void WriteSymbolFile (Guid guid) + public void OpenCompilerGeneratedBlock (int start_offset) { - foreach (SourceMethod method in methods) { - method.SourceFile.Entry.DefineMethod ( - method.Method.Name, method.Method.Token, - method.Locals, method.Lines, method.Blocks, - method.Start.Row, method.End.Row, - method.Method.NamespaceID); - } + if (current_method == null) + return; - using (FileStream fs = new FileStream (filename, FileMode.Create, FileAccess.Write)) { - file.CreateSymbolFile (guid, fs); - } + current_method.StartBlock (CodeBlockEntry.Type.CompilerGenerated, + start_offset); } - protected class SourceMethod + public void CloseCompilerGeneratedBlock (int end_offset) { - LineNumberEntry [] lines; - private ArrayList _locals; - private ArrayList _blocks; - private Stack _block_stack; - private int next_block_id = 0; - private ISourceMethod _method; - private ISourceFile _file; - private LineNumberEntry _start, _end; - - private LexicalBlockEntry _implicit_block; - - public SourceMethod (ISourceFile file, ISourceMethod method, - int startLine, int startColumn, - int endLine, int endColumn) - { - this._file = file; - this._method = method; - - this._start = new LineNumberEntry (startLine, 0); - this._end = new LineNumberEntry (endLine, 0); - - this._implicit_block = new LexicalBlockEntry (0, 0); - } - - public void StartBlock (int startOffset) - { - LexicalBlockEntry block = new LexicalBlockEntry ( - ++next_block_id, startOffset); - if (_block_stack == null) - _block_stack = new Stack (); - _block_stack.Push (block); - if (_blocks == null) - _blocks = new ArrayList (); - _blocks.Add (block); - } - - public void EndBlock (int endOffset) - { - LexicalBlockEntry block = - (LexicalBlockEntry) _block_stack.Pop (); - - block.Close (endOffset); - } - - public LexicalBlockEntry[] Blocks { - get { - if (_blocks == null) - return new LexicalBlockEntry [0]; - else { - LexicalBlockEntry[] retval = - new LexicalBlockEntry [_blocks.Count]; - _blocks.CopyTo (retval, 0); - return retval; - } - } - } + if (current_method == null) + return; - public LexicalBlockEntry CurrentBlock { - get { - if ((_block_stack != null) && (_block_stack.Count > 0)) - return (LexicalBlockEntry) _block_stack.Peek (); - else - return _implicit_block; - } - } + current_method.EndBlock (end_offset); + } - public LineNumberEntry[] Lines { - get { - return lines; - } - } + public void StartIteratorBody (int start_offset) + { + current_method.StartBlock (CodeBlockEntry.Type.IteratorBody, + start_offset); + } - 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 EndIteratorBody (int end_offset) + { + current_method.EndBlock (end_offset); + } - public void AddLocal (int index, string name, byte[] signature) - { - if (_locals == null) - _locals = new ArrayList (); - _locals.Add (new LocalVariableEntry ( - index, name, signature, CurrentBlock.Index)); - } + public void StartIteratorDispatcher (int start_offset) + { + current_method.StartBlock (CodeBlockEntry.Type.IteratorDispatcher, + start_offset); + } - public ISourceFile SourceFile { - get { return _file; } - } + public void EndIteratorDispatcher (int end_offset) + { + current_method.EndBlock (end_offset); + } - public ISourceMethod Method { - get { return _method; } - } + public void DefineAnonymousScope (int id) + { + file.DefineAnonymousScope (id); + } - public LineNumberEntry Start { - get { return _start; } - } + public void WriteSymbolFile (Guid guid) + { + foreach (SourceMethodBuilder method in methods) + method.DefineMethod (file); - public LineNumberEntry End { - get { return _end; } + try { + // We mmap the file, so unlink the previous version since it may be in use + File.Delete (filename); + } catch { + // We can safely ignore } - - // - // Passes on the lines from the MonoSymbolWriter. This method is - // free to mutate the lns array, and it does. - // - internal void SetLineNumbers (LineNumberEntry [] lns, int count) - { - int pos = 0; - - int last_offset = -1; - int last_row = -1; - for (int i = 0; i < count; i++) { - LineNumberEntry line = lns [i]; - - if (line.Offset > last_offset) { - if (last_row >= 0) - lns [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; - } - } - - lines = new LineNumberEntry [count + ((last_row >= 0) ? 1 : 0)]; - Array.Copy (lns, lines, pos); - if (last_row >= 0) - lines [pos] = new LineNumberEntry ( - last_row, last_offset); + using (FileStream fs = new FileStream (filename, FileMode.Create, FileAccess.Write)) { + file.CreateSymbolFile (guid, fs); } } }