5 // Jb Evain (jbevain@gmail.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 namespace Mono.Cecil.Mdb {
31 using System.Collections;
32 using SDS = System.Diagnostics.SymbolStore;
33 using Mono.CompilerServices.SymbolWriter;
36 class MdbWriter : ISymbolWriter {
38 SymbolWriterImpl m_writer;
39 Hashtable m_documents;
41 public MdbWriter (SymbolWriterImpl writer)
44 m_documents = new Hashtable ();
47 public void Write (MethodBody body, byte [][] variables)
49 Document document = CreateDocuments (body);
50 if (document != null) {
51 SDS.ISymbolDocumentWriter docWriter = GetDocument (document);
52 m_writer.SetMethodSourceRange (docWriter, 1, 1, docWriter, int.MaxValue, int.MaxValue);
55 m_writer.OpenMethod (new SDS.SymbolToken ((int) body.Method.MetadataToken.ToUInt ()));
56 m_writer.SetSymAttribute (new SDS.SymbolToken (), "__name", System.Text.Encoding.UTF8.GetBytes (body.Method.Name));
58 CreateScopes (body, body.Scopes, variables);
59 m_writer.CloseMethod ();
62 void CreateScopes (MethodBody body, ScopeCollection scopes, byte [][] variables)
64 foreach (Scope s in scopes) {
65 int startOffset = s.Start.Offset;
66 int endOffset = s.End == body.Instructions.Outside ?
67 body.Instructions[body.Instructions.Count - 1].Offset + 1 :
70 m_writer.OpenScope (startOffset);
71 m_writer.UsingNamespace (body.Method.DeclaringType.Namespace);
72 m_writer.OpenNamespace (body.Method.DeclaringType.Namespace);
74 int start = body.Instructions.IndexOf (s.Start);
75 int end = s.End == body.Instructions.Outside ?
76 body.Instructions.Count - 1 :
77 body.Instructions.IndexOf (s.End);
79 ArrayList instructions = new ArrayList();
80 for (int i = start; i <= end; i++)
81 if (body.Instructions [i].SequencePoint != null)
82 instructions.Add (body.Instructions [i]);
86 int [] offsets = new int [instructions.Count];
87 int [] startRows = new int [instructions.Count];
88 int [] startCols = new int [instructions.Count];
89 int [] endRows = new int [instructions.Count];
90 int [] endCols = new int [instructions.Count];
92 for (int i = 0; i < instructions.Count; i++) {
93 Instruction instr = (Instruction) instructions [i];
94 offsets [i] = instr.Offset;
97 doc = instr.SequencePoint.Document;
99 startRows [i] = instr.SequencePoint.StartLine;
100 startCols [i] = instr.SequencePoint.StartColumn;
101 endRows [i] = instr.SequencePoint.EndLine;
102 endCols [i] = instr.SequencePoint.EndColumn;
105 m_writer.DefineSequencePoints (GetDocument (doc),
106 offsets, startRows, startCols, endRows, endCols);
108 CreateLocalVariables (s, startOffset, endOffset, variables);
110 CreateScopes (body, s.Scopes, variables);
111 m_writer.CloseNamespace ();
113 m_writer.CloseScope (endOffset);
117 void CreateLocalVariables (Scope s, int startOffset, int endOffset, byte [][] variables)
119 for (int i = 0; i < s.Variables.Count; i++) {
120 VariableDefinition var = s.Variables [i];
121 m_writer.DefineLocalVariable (
124 variables [var.Index],
134 Document CreateDocuments (MethodBody body)
137 foreach (Instruction instr in body.Instructions) {
138 if (instr.SequencePoint == null)
142 doc = instr.SequencePoint.Document;
144 GetDocument (instr.SequencePoint.Document);
150 SDS.ISymbolDocumentWriter GetDocument (Document document)
152 SDS.ISymbolDocumentWriter docWriter = m_documents [document.Url] as SDS.ISymbolDocumentWriter;
153 if (docWriter != null)
156 docWriter = m_writer.DefineDocument (
158 GuidAttribute.GetGuidFromValue ((int) document.Language, typeof (DocumentLanguage)),
159 GuidAttribute.GetGuidFromValue ((int) document.LanguageVendor, typeof (DocumentLanguageVendor)),
160 GuidAttribute.GetGuidFromValue ((int) document.Type, typeof (DocumentType)));
162 m_documents [document.Url] = docWriter;
166 public void Dispose ()