2 // (C) Sergey Chaban (serge@wildwestsoftware.com)
\r
5 using System.Collections;
\r
6 using System.Reflection;
\r
7 using System.Reflection.Emit;
\r
9 namespace Mono.ILASM {
\r
12 public class MethodName {
\r
13 private static int methodCount = 0;
\r
15 private bool isCtor;
\r
16 private string name;
\r
20 public MethodName () : this ("M_" + (methodCount++))
\r
26 /// <param name="name"></param>
\r
27 public MethodName (string name) : this (name, false)
\r
33 /// <param name="name"></param>
\r
34 /// <param name="ctor"></param>
\r
35 public MethodName (string name, bool ctor)
\r
44 public string Name {
\r
56 public bool IsCtor {
\r
71 public class Method {
\r
73 private MethodName name;
\r
74 private MethodAttributes attrs;
\r
75 private CallingConventions callConv;
\r
76 private string retType;
\r
77 private MethodBuilder method_builder;
\r
78 private bool entry_point = false;
\r
80 private ArrayList param_list;
\r
81 private ArrayList instructions;
\r
82 private ArrayList local_list;
\r
88 name = new MethodName ();
\r
95 public string Name {
\r
107 /// <param name="name"></param>
\r
108 public void SetMethodName (MethodName name)
\r
116 public bool IsCtor {
\r
118 return name.IsCtor;
\r
121 name.IsCtor = value;
\r
128 public string RetType {
\r
140 public MethodAttributes Attrs {
\r
152 public CallingConventions CallConv {
\r
164 public bool IsEntryPoint {
\r
166 return entry_point;
\r
169 entry_point = value;
\r
175 /// <param name="instr"></param>
\r
176 public void AddInstruction (InstrBase instr)
\r
178 if (instr == null) {
\r
179 throw new InternalErrorException ("<null> instruction");
\r
182 if (instructions == null) {
\r
183 this.instructions = new ArrayList ();
\r
186 instructions.Add (instr);
\r
189 public void AddLocal (DictionaryEntry local)
\r
191 if (local_list == null)
\r
192 local_list = new ArrayList ();
\r
194 local_list.Add (local);
\r
198 public void SetParamList (ArrayList param_list)
\r
200 this.param_list = param_list;
\r
205 public int InstrCount {
\r
207 return (instructions != null) ? instructions.Count : 0;
\r
213 /// <returns></returns>
\r
214 public override string ToString ()
\r
216 return String.Format ("IL.Method [Name: {0}, Attrs: {1}, CallConv: {2}, RetType: {3}, Instr: {4}]",
\r
217 Name, Attrs, CallConv, RetType, InstrCount);
\r
220 public MethodBuilder Builder {
\r
222 return method_builder;
\r
226 public void Resolve (Class host)
\r
228 Type return_type = host.CodeGen.TypeManager[RetType];
\r
229 method_builder = host.TypeBuilder.DefineMethod (Name, Attrs,
\r
230 CallConv, return_type, CreateTypeList (host.CodeGen.TypeManager));
\r
235 /// <param name="tb"></param>
\r
236 public void Emit (Class host)
\r
238 TypeBuilder tb = host.TypeBuilder;
\r
242 ILGenerator ilgen = method_builder.GetILGenerator ();
\r
244 if (local_list != null) {
\r
245 foreach (DictionaryEntry local in local_list) {
\r
246 Type local_type = host.CodeGen.TypeManager[(string)local.Key];
\r
247 if (local_type == null) {
\r
248 Console.WriteLine ("Could not find type: {0}", local.Key);
\r
251 ilgen.DeclareLocal (local_type);
\r
255 if (instructions != null) {
\r
256 foreach (InstrBase instr in instructions)
\r
257 instr.Emit (ilgen, host);
\r
262 private Type[] CreateTypeList (TypeManager type_manager)
\r
264 if (param_list == null)
\r
265 return new Type[0];
\r
267 int count = param_list.Count;
\r
268 Type[] type_list = new Type[count];
\r
270 for (int i=0; i<count; i++) {
\r
271 type_list[i] = type_manager[(string) param_list[i]];
\r