Resolve parameter types in a more proper manner.
[mono.git] / mcs / ilasm / codegen / Instructions.cs
1 // Instructions.cs\r
2 // (C) Sergey Chaban (serge@wildwestsoftware.com)\r
3 \r
4 using System;\r
5 using System.Reflection;\r
6 using System.Reflection.Emit;\r
7 \r
8 namespace Mono.ILASM {\r
9 \r
10 \r
11         /// <summary>\r
12         /// </summary>\r
13         public class InstrNone : InstrBase {\r
14 \r
15                 /// <summary>\r
16                 /// </summary>\r
17                 /// <param name="tok"></param>\r
18                 public InstrNone (OpCode op) : base (op)\r
19                 {\r
20                 }\r
21 \r
22                 /// <summary>\r
23                 /// </summary>\r
24                 /// <param name="ilgen"></param>\r
25                 public override void Emit (ILGenerator ilgen)\r
26                 {\r
27                         ilgen.Emit (this.Opcode);\r
28                 }\r
29         }\r
30 \r
31 \r
32         /// <summary>\r
33         /// </summary>\r
34         public class InstrVar : InstrBase {\r
35 \r
36                 private object operand;\r
37 \r
38                 /// <summary>\r
39                 /// </summary>\r
40                 /// <param name="tok"></param>\r
41                 public InstrVar (OpCode op, object operand) : base (op)\r
42                 {\r
43                         this.operand = operand;\r
44                 }\r
45 \r
46 \r
47                 /// <summary>\r
48                 /// </summary>\r
49                 /// <param name="ilgen"></param>\r
50                 public override void Emit (ILGenerator ilgen)\r
51                 {\r
52                         if (operand is string) {\r
53                                 ilgen.Emit (Opcode, operand as string);\r
54                         } else if (operand is Int32) {\r
55                                 ilgen.Emit (Opcode, (Int32)operand);\r
56                         }\r
57                 }\r
58         }\r
59 \r
60 \r
61         /// <summary>\r
62         /// </summary>\r
63         public class InstrI : InstrBase {\r
64 \r
65                 private int operand;\r
66 \r
67                 /// <summary>\r
68                 /// </summary>\r
69                 /// <param name="tok"></param>\r
70                 public InstrI (OpCode op, int operand) : base (op) {\r
71                         this.operand = operand;\r
72                 }\r
73 \r
74 \r
75                 /// <summary>\r
76                 /// </summary>\r
77                 /// <param name="ilgen"></param>\r
78                 public override void Emit (ILGenerator ilgen) {\r
79                                 ilgen.Emit (Opcode, operand);\r
80                 }\r
81         }\r
82 \r
83 \r
84         /// <summary>\r
85         /// </summary>\r
86         public class InstrI8 : InstrBase {\r
87 \r
88                 private long operand;\r
89 \r
90                 /// <summary>\r
91                 /// </summary>\r
92                 /// <param name="tok"></param>\r
93                 public InstrI8 (OpCode op, long operand) : base (op) {\r
94                         this.operand = operand;\r
95                 }\r
96 \r
97 \r
98                 /// <summary>\r
99                 /// </summary>\r
100                 /// <param name="ilgen"></param>\r
101                 public override void Emit (ILGenerator ilgen) {\r
102                         ilgen.Emit (Opcode, operand);\r
103                 }\r
104         }\r
105 \r
106 \r
107         /// <summary>\r
108         /// </summary>\r
109         public class InstrR : InstrBase {\r
110 \r
111                 private double operand;\r
112 \r
113                 /// <summary>\r
114                 /// </summary>\r
115                 /// <param name="tok"></param>\r
116                 public InstrR (OpCode op, double operand) : base (op) {\r
117                         this.operand = operand;\r
118                 }\r
119 \r
120 \r
121                 /// <summary>\r
122                 /// </summary>\r
123                 /// <param name="ilgen"></param>\r
124                 public override void Emit (ILGenerator ilgen) {\r
125                         if (Opcode.Name.IndexOf (".r4") != -1) {\r
126                                 ilgen.Emit (Opcode, (float) operand);\r
127                         } else {\r
128                                 ilgen.Emit (Opcode, operand);\r
129                         }\r
130                 }\r
131         }\r
132 \r
133 \r
134 \r
135         /// <summary>\r
136         /// </summary>\r
137         public class InstrString : InstrBase {\r
138 \r
139                 private string operand;\r
140 \r
141                 /// <summary>\r
142                 /// </summary>\r
143                 /// <param name="tok"></param>\r
144                 public InstrString (OpCode op, string operand) : base (op) {\r
145                         this.operand = operand;\r
146                 }\r
147 \r
148 \r
149                 /// <summary>\r
150                 /// </summary>\r
151                 /// <param name="ilgen"></param>\r
152                 public override void Emit (ILGenerator ilgen) {\r
153                         ilgen.Emit (Opcode, operand);\r
154                 }\r
155         }\r
156 \r
157 \r
158 \r
159         /// <summary>\r
160         ///    void System.Console::WriteLine(string)\r
161         /// </summary>\r
162         public class InstrCall : InstrBase {\r
163                 \r
164                 private string return_type;\r
165                 private string assembly_name;\r
166                 private string calling_type;\r
167                 private string method_name;\r
168                 private string args;\r
169         \r
170                 /// <summary>\r
171                 /// </summary>\r
172                 /// <param name="tok"></param>\r
173                 public InstrCall (OpCode op, string return_type, string assembly_name, \r
174                                 string calling_type, string method_name, string args) : base (op) {\r
175                         \r
176                         this.return_type = return_type;\r
177                         this.assembly_name = assembly_name;\r
178                         this.calling_type = calling_type;\r
179                         this.method_name = method_name;\r
180                         this.args = args;\r
181                         \r
182                 }\r
183 \r
184 \r
185                 /// <summary>\r
186                 /// </summary>\r
187                 /// <param name="ilgen"></param>\r
188                 public override void Emit (ILGenerator ilgen) {\r
189                         // Create MethodInfo\r
190                         Assembly assembly = Assembly.LoadWithPartialName (assembly_name);               \r
191                         Type type_to_call = assembly.GetType (calling_type);\r
192                         MethodInfo calling_method = type_to_call.GetMethod (method_name, TypeArray ());\r
193                         \r
194                         ilgen.Emit (Opcode, calling_method);\r
195                 \r
196                 }\r
197 \r
198                 private Type[] TypeArray ()\r
199                 {\r
200                         string[] type_name_list = args.Split (',');\r
201                         Type[] type_list = new Type[type_name_list.Length];\r
202                         Types type_manager = new Types ();\r
203 \r
204                         for (int i=0; i<type_name_list.Length; i++) {\r
205                                 type_list[i] = type_manager.Lookup (type_name_list[i]);\r
206                         }\r
207 \r
208                         return type_list;\r
209                 }\r
210 \r
211                 \r
212         }\r
213 }\r