SourceMethodBuilder.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. using System;
  2. using System.Collections.Generic;
  3. namespace Mono.CompilerServices.SymbolWriter
  4. {
  5. public class SourceMethodBuilder
  6. {
  7. private List<LocalVariableEntry> _locals;
  8. private List<CodeBlockEntry> _blocks;
  9. private List<ScopeVariable> _scope_vars;
  10. private Stack<CodeBlockEntry> _block_stack;
  11. private string _real_name;
  12. private IMethodDef _method;
  13. private ICompileUnit _comp_unit;
  14. private int _ns_id;
  15. private LineNumberEntry[] method_lines;
  16. private int method_lines_pos = 0;
  17. public CodeBlockEntry[] Blocks
  18. {
  19. get
  20. {
  21. CodeBlockEntry[] result;
  22. if (this._blocks == null)
  23. {
  24. result = new CodeBlockEntry[0];
  25. }
  26. else
  27. {
  28. CodeBlockEntry[] retval = new CodeBlockEntry[this._blocks.Count];
  29. this._blocks.CopyTo(retval, 0);
  30. result = retval;
  31. }
  32. return result;
  33. }
  34. }
  35. public CodeBlockEntry CurrentBlock
  36. {
  37. get
  38. {
  39. CodeBlockEntry result;
  40. if (this._block_stack != null && this._block_stack.Count > 0)
  41. {
  42. result = this._block_stack.Peek();
  43. }
  44. else
  45. {
  46. result = null;
  47. }
  48. return result;
  49. }
  50. }
  51. public LocalVariableEntry[] Locals
  52. {
  53. get
  54. {
  55. LocalVariableEntry[] result;
  56. if (this._locals == null)
  57. {
  58. result = new LocalVariableEntry[0];
  59. }
  60. else
  61. {
  62. LocalVariableEntry[] retval = new LocalVariableEntry[this._locals.Count];
  63. this._locals.CopyTo(retval, 0);
  64. result = retval;
  65. }
  66. return result;
  67. }
  68. }
  69. public ScopeVariable[] ScopeVariables
  70. {
  71. get
  72. {
  73. ScopeVariable[] result;
  74. if (this._scope_vars == null)
  75. {
  76. result = new ScopeVariable[0];
  77. }
  78. else
  79. {
  80. ScopeVariable[] retval = new ScopeVariable[this._scope_vars.Count];
  81. this._scope_vars.CopyTo(retval);
  82. result = retval;
  83. }
  84. return result;
  85. }
  86. }
  87. public string RealMethodName
  88. {
  89. get
  90. {
  91. return this._real_name;
  92. }
  93. }
  94. public ICompileUnit SourceFile
  95. {
  96. get
  97. {
  98. return this._comp_unit;
  99. }
  100. }
  101. public IMethodDef Method
  102. {
  103. get
  104. {
  105. return this._method;
  106. }
  107. }
  108. public SourceMethodBuilder(ICompileUnit comp_unit, int ns_id, IMethodDef method)
  109. {
  110. this._comp_unit = comp_unit;
  111. this._method = method;
  112. this._ns_id = ns_id;
  113. this.method_lines = new LineNumberEntry[32];
  114. }
  115. public void MarkSequencePoint(int offset, SourceFileEntry file, int line, int column, bool is_hidden)
  116. {
  117. if (this.method_lines_pos == this.method_lines.Length)
  118. {
  119. LineNumberEntry[] tmp = this.method_lines;
  120. this.method_lines = new LineNumberEntry[this.method_lines.Length * 2];
  121. Array.Copy(tmp, this.method_lines, this.method_lines_pos);
  122. }
  123. int file_idx = (file != null) ? file.Index : 0;
  124. this.method_lines[this.method_lines_pos++] = new LineNumberEntry(file_idx, line, offset, is_hidden);
  125. }
  126. public void StartBlock(CodeBlockEntry.Type type, int start_offset)
  127. {
  128. if (this._block_stack == null)
  129. {
  130. this._block_stack = new Stack<CodeBlockEntry>();
  131. }
  132. if (this._blocks == null)
  133. {
  134. this._blocks = new List<CodeBlockEntry>();
  135. }
  136. int parent = (this.CurrentBlock != null) ? this.CurrentBlock.Index : -1;
  137. CodeBlockEntry block = new CodeBlockEntry(this._blocks.Count + 1, parent, type, start_offset);
  138. this._block_stack.Push(block);
  139. this._blocks.Add(block);
  140. }
  141. public void EndBlock(int end_offset)
  142. {
  143. CodeBlockEntry block = this._block_stack.Pop();
  144. block.Close(end_offset);
  145. }
  146. public void AddLocal(int index, string name)
  147. {
  148. if (this._locals == null)
  149. {
  150. this._locals = new List<LocalVariableEntry>();
  151. }
  152. int block_idx = (this.CurrentBlock != null) ? this.CurrentBlock.Index : 0;
  153. this._locals.Add(new LocalVariableEntry(index, name, block_idx));
  154. }
  155. public void AddScopeVariable(int scope, int index)
  156. {
  157. if (this._scope_vars == null)
  158. {
  159. this._scope_vars = new List<ScopeVariable>();
  160. }
  161. this._scope_vars.Add(new ScopeVariable(scope, index));
  162. }
  163. public void SetRealMethodName(string name)
  164. {
  165. this._real_name = name;
  166. }
  167. public void DefineMethod(MonoSymbolFile file)
  168. {
  169. LineNumberEntry[] lines = new LineNumberEntry[this.method_lines_pos];
  170. Array.Copy(this.method_lines, lines, this.method_lines_pos);
  171. 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);
  172. file.AddMethod(entry);
  173. }
  174. }
  175. }