update Mono.Cecil
[mono.git] / mcs / class / Mono.Cecil / Mono.Cecil.Cil / ILProcessor.cs
1 //
2 // ILProcessor.cs
3 //
4 // Author:
5 //   Jb Evain (jbevain@gmail.com)
6 //
7 // Copyright (c) 2008 - 2011 Jb Evain
8 //
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:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
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.
27 //
28
29 using System;
30
31 using Mono.Collections.Generic;
32
33 namespace Mono.Cecil.Cil {
34
35         public sealed class ILProcessor {
36
37                 readonly MethodBody body;
38                 readonly Collection<Instruction> instructions;
39
40                 public MethodBody Body {
41                         get { return body; }
42                 }
43
44                 internal ILProcessor (MethodBody body)
45                 {
46                         this.body = body;
47                         this.instructions = body.Instructions;
48                 }
49
50                 public Instruction Create (OpCode opcode)
51                 {
52                         return Instruction.Create (opcode);
53                 }
54
55                 public Instruction Create (OpCode opcode, TypeReference type)
56                 {
57                         return Instruction.Create (opcode, type);
58                 }
59
60                 public Instruction Create (OpCode opcode, CallSite site)
61                 {
62                         return Instruction.Create (opcode, site);
63                 }
64
65                 public Instruction Create (OpCode opcode, MethodReference method)
66                 {
67                         return Instruction.Create (opcode, method);
68                 }
69
70                 public Instruction Create (OpCode opcode, FieldReference field)
71                 {
72                         return Instruction.Create (opcode, field);
73                 }
74
75                 public Instruction Create (OpCode opcode, string value)
76                 {
77                         return Instruction.Create (opcode, value);
78                 }
79
80                 public Instruction Create (OpCode opcode, sbyte value)
81                 {
82                         return Instruction.Create (opcode, value);
83                 }
84
85                 public Instruction Create (OpCode opcode, byte value)
86                 {
87                         if (opcode.OperandType == OperandType.ShortInlineVar)
88                                 return Instruction.Create (opcode, body.Variables [value]);
89
90                         if (opcode.OperandType == OperandType.ShortInlineArg)
91                                 return Instruction.Create (opcode, body.GetParameter (value));
92
93                         return Instruction.Create (opcode, value);
94                 }
95
96                 public Instruction Create (OpCode opcode, int value)
97                 {
98                         if (opcode.OperandType == OperandType.InlineVar)
99                                 return Instruction.Create (opcode, body.Variables [value]);
100
101                         if (opcode.OperandType == OperandType.InlineArg)
102                                 return Instruction.Create (opcode, body.GetParameter (value));
103
104                         return Instruction.Create (opcode, value);
105                 }
106
107                 public Instruction Create (OpCode opcode, long value)
108                 {
109                         return Instruction.Create (opcode, value);
110                 }
111
112                 public Instruction Create (OpCode opcode, float value)
113                 {
114                         return Instruction.Create (opcode, value);
115                 }
116
117                 public Instruction Create (OpCode opcode, double value)
118                 {
119                         return Instruction.Create (opcode, value);
120                 }
121
122                 public Instruction Create (OpCode opcode, Instruction target)
123                 {
124                         return Instruction.Create (opcode, target);
125                 }
126
127                 public Instruction Create (OpCode opcode, Instruction [] targets)
128                 {
129                         return Instruction.Create (opcode, targets);
130                 }
131
132                 public Instruction Create (OpCode opcode, VariableDefinition variable)
133                 {
134                         return Instruction.Create (opcode, variable);
135                 }
136
137                 public Instruction Create (OpCode opcode, ParameterDefinition parameter)
138                 {
139                         return Instruction.Create (opcode, parameter);
140                 }
141
142                 public void Emit (OpCode opcode)
143                 {
144                         Append (Create (opcode));
145                 }
146
147                 public void Emit (OpCode opcode, TypeReference type)
148                 {
149                         Append (Create (opcode, type));
150                 }
151
152                 public void Emit (OpCode opcode, MethodReference method)
153                 {
154                         Append (Create (opcode, method));
155                 }
156
157                 public void Emit (OpCode opcode, CallSite site)
158                 {
159                         Append (Create (opcode, site));
160                 }
161
162                 public void Emit (OpCode opcode, FieldReference field)
163                 {
164                         Append (Create (opcode, field));
165                 }
166
167                 public void Emit (OpCode opcode, string value)
168                 {
169                         Append (Create (opcode, value));
170                 }
171
172                 public void Emit (OpCode opcode, byte value)
173                 {
174                         Append (Create (opcode, value));
175                 }
176
177                 public void Emit (OpCode opcode, sbyte value)
178                 {
179                         Append (Create (opcode, value));
180                 }
181
182                 public void Emit (OpCode opcode, int value)
183                 {
184                         Append (Create (opcode, value));
185                 }
186
187                 public void Emit (OpCode opcode, long value)
188                 {
189                         Append (Create (opcode, value));
190                 }
191
192                 public void Emit (OpCode opcode, float value)
193                 {
194                         Append (Create (opcode, value));
195                 }
196
197                 public void Emit (OpCode opcode, double value)
198                 {
199                         Append (Create (opcode, value));
200                 }
201
202                 public void Emit (OpCode opcode, Instruction target)
203                 {
204                         Append (Create (opcode, target));
205                 }
206
207                 public void Emit (OpCode opcode, Instruction [] targets)
208                 {
209                         Append (Create (opcode, targets));
210                 }
211
212                 public void Emit (OpCode opcode, VariableDefinition variable)
213                 {
214                         Append (Create (opcode, variable));
215                 }
216
217                 public void Emit (OpCode opcode, ParameterDefinition parameter)
218                 {
219                         Append (Create (opcode, parameter));
220                 }
221
222                 public void InsertBefore (Instruction target, Instruction instruction)
223                 {
224                         if (target == null)
225                                 throw new ArgumentNullException ("target");
226                         if (instruction == null)
227                                 throw new ArgumentNullException ("instruction");
228
229                         var index = instructions.IndexOf (target);
230                         if (index == -1)
231                                 throw new ArgumentOutOfRangeException ("target");
232
233                         instructions.Insert (index, instruction);
234                 }
235
236                 public void InsertAfter (Instruction target, Instruction instruction)
237                 {
238                         if (target == null)
239                                 throw new ArgumentNullException ("target");
240                         if (instruction == null)
241                                 throw new ArgumentNullException ("instruction");
242
243                         var index = instructions.IndexOf (target);
244                         if (index == -1)
245                                 throw new ArgumentOutOfRangeException ("target");
246
247                         instructions.Insert (index + 1, instruction);
248                 }
249
250                 public void Append (Instruction instruction)
251                 {
252                         if (instruction == null)
253                                 throw new ArgumentNullException ("instruction");
254
255                         instructions.Add (instruction);
256                 }
257
258                 public void Replace (Instruction target, Instruction instruction)
259                 {
260                         if (target == null)
261                                 throw new ArgumentNullException ("target");
262                         if (instruction == null)
263                                 throw new ArgumentNullException ("instruction");
264
265                         InsertAfter (target, instruction);
266                         Remove (target);
267                 }
268
269                 public void Remove (Instruction instruction)
270                 {
271                         if (instruction == null)
272                                 throw new ArgumentNullException ("instruction");
273
274                         if (!instructions.Remove (instruction))
275                                 throw new ArgumentOutOfRangeException ("instruction");
276                 }
277         }
278 }