* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / ilasm / codegen / Method.cs
1 // Method.cs\r
2 // (C) Sergey Chaban (serge@wildwestsoftware.com)\r
3 \r
4 using System;\r
5 using System.Collections;\r
6 using System.Reflection;\r
7 using System.Reflection.Emit;\r
8 \r
9 namespace Mono.ILASM {\r
10 \r
11 \r
12         public class MethodName {\r
13                 private static int methodCount = 0;\r
14 \r
15                 private bool isCtor;\r
16                 private string name;\r
17                 \r
18                 /// <summary>\r
19                 /// </summary>\r
20                 public MethodName () : this ("M_" + (methodCount++))\r
21                 {\r
22                 }\r
23 \r
24                 /// <summary>\r
25                 /// </summary>\r
26                 /// <param name="name"></param>\r
27                 public MethodName (string name) : this (name, false)\r
28                 {\r
29                 }\r
30 \r
31                 /// <summary>\r
32                 /// </summary>\r
33                 /// <param name="name"></param>\r
34                 /// <param name="ctor"></param>\r
35                 public MethodName (string name, bool ctor)\r
36                 {\r
37                         this.name = name;\r
38                         this.isCtor = ctor;\r
39                 }\r
40 \r
41 \r
42                 /// <summary>\r
43                 /// </summary>\r
44                 public string Name {\r
45                         get {\r
46                                 return name;\r
47                         }\r
48                         set {\r
49                                 name = value;\r
50                         }\r
51                 }\r
52 \r
53 \r
54                 /// <summary>\r
55                 /// </summary>\r
56                 public bool IsCtor {\r
57                         get {\r
58                                 return isCtor;\r
59                         }\r
60                         set {\r
61                                 isCtor = value;\r
62                         }\r
63                 }\r
64 \r
65         }\r
66 \r
67 \r
68 \r
69         /// <summary>\r
70         /// </summary>\r
71         public class Method {\r
72 \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
79 \r
80                 private ArrayList param_list;\r
81                 private ArrayList instructions;\r
82                 private ArrayList local_list;\r
83 \r
84                 /// <summary>\r
85                 /// </summary>\r
86                 public Method ()\r
87                 {\r
88                         name = new MethodName ();\r
89                         attrs = 0;\r
90                 }\r
91 \r
92 \r
93                 /// <summary>\r
94                 /// </summary>\r
95                 public string Name {\r
96                         get {\r
97                                 return name.Name;\r
98                         }\r
99                         set {\r
100                                 name.Name = value;\r
101                         }\r
102                 }\r
103 \r
104 \r
105                 /// <summary>\r
106                 /// </summary>\r
107                 /// <param name="name"></param>\r
108                 public void SetMethodName (MethodName name)\r
109                 {\r
110                         this.name = name;\r
111                 }\r
112 \r
113 \r
114                 /// <summary>\r
115                 /// </summary>\r
116                 public bool IsCtor {\r
117                         get {\r
118                                 return name.IsCtor;\r
119                         }\r
120                         set {\r
121                                 name.IsCtor = value;\r
122                         }\r
123                 }\r
124 \r
125 \r
126                 /// <summary>\r
127                 /// </summary>\r
128                 public string RetType {\r
129                         get {\r
130                                 return retType;\r
131                         }\r
132                         set {\r
133                                 retType = value;\r
134                         }\r
135                 }\r
136 \r
137 \r
138                 /// <summary>\r
139                 /// </summary>\r
140                 public MethodAttributes Attrs {\r
141                         get {\r
142                                 return attrs;\r
143                         }\r
144                         set {\r
145                                 attrs = value;\r
146                         }\r
147                 }\r
148 \r
149 \r
150                 /// <summary>\r
151                 /// </summary>\r
152                 public CallingConventions CallConv {\r
153                         get {\r
154                                 return callConv;\r
155                         }\r
156                         set {\r
157                                 callConv = value;\r
158                         }\r
159                 }\r
160 \r
161 \r
162                 /// <summary>\r
163                 /// </summary>\r
164                 public bool IsEntryPoint {\r
165                         get {\r
166                                 return entry_point;\r
167                         }\r
168                         set {\r
169                                 entry_point = value;\r
170                         }\r
171                 }               \r
172 \r
173                 /// <summary>\r
174                 /// </summary>\r
175                 /// <param name="instr"></param>\r
176                 public void AddInstruction (InstrBase instr)\r
177                 {\r
178                         if (instr == null) {\r
179                                 throw new InternalErrorException ("<null> instruction");\r
180                         }\r
181 \r
182                         if (instructions == null) {\r
183                                 this.instructions = new ArrayList ();\r
184                         }\r
185 \r
186                         instructions.Add (instr);\r
187                 }\r
188 \r
189                 public void AddLocal (DictionaryEntry local)\r
190                 {\r
191                         if (local_list == null)\r
192                                 local_list = new ArrayList ();\r
193 \r
194                         local_list.Add (local);\r
195         \r
196                 }\r
197 \r
198                 public void SetParamList (ArrayList param_list)\r
199                 {\r
200                         this.param_list = param_list;\r
201                 }\r
202 \r
203                 /// <summary>\r
204                 /// </summary>\r
205                 public int InstrCount {\r
206                         get {\r
207                                 return (instructions != null) ? instructions.Count : 0;\r
208                         }\r
209                 }\r
210 \r
211                 /// <summary>\r
212                 /// </summary>\r
213                 /// <returns></returns>\r
214                 public override string ToString ()\r
215                 {\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
218                 }\r
219 \r
220                 public MethodBuilder Builder {\r
221                         get {\r
222                                 return method_builder;\r
223                         }\r
224                 }\r
225 \r
226                 public void Resolve (Class host)\r
227                 {\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
231                 }\r
232 \r
233                 /// <summary>\r
234                 /// </summary>\r
235                 /// <param name="tb"></param>\r
236                 public void Emit (Class host)\r
237                 {\r
238                         TypeBuilder tb = host.TypeBuilder;\r
239 \r
240                         if (IsCtor) {\r
241                         } else {\r
242                                 ILGenerator ilgen = method_builder.GetILGenerator ();\r
243 \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
249                                                         return;\r
250                                                 }\r
251                                                 ilgen.DeclareLocal (local_type);\r
252                                         }\r
253                                 }\r
254 \r
255                                 if (instructions != null) {\r
256                                         foreach (InstrBase instr in instructions)\r
257                                                 instr.Emit (ilgen, host);\r
258                                 }\r
259                         }\r
260                 }\r
261 \r
262                 private Type[] CreateTypeList (TypeManager type_manager)\r
263                 {\r
264                         if (param_list == null)\r
265                                 return new Type[0];\r
266 \r
267                         int count = param_list.Count;\r
268                         Type[] type_list = new Type[count];\r
269                         \r
270                         for (int i=0; i<count; i++) {\r
271                                 type_list[i] = type_manager[(string) param_list[i]];\r
272                         }\r
273                 \r
274                         return type_list;\r
275                 }\r
276 \r
277         }\r
278 \r
279         \r
280 }\r