5 // Jb Evain (jbevain@gmail.com)
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
29 namespace Mono.Cecil.Cil {
32 using SR = System.Reflection;
34 public sealed class CilWorker {
37 InstructionCollection m_instrs;
39 internal CilWorker (MethodBody body)
42 m_instrs = m_mbody.Instructions;
45 public MethodBody GetBody ()
50 public Instruction Create (OpCode opcode)
52 if (opcode.OperandType != OperandType.InlineNone)
53 throw new ArgumentException ("opcode");
55 return FinalCreate (opcode);
58 public Instruction Create (OpCode opcode, TypeReference type)
60 if (opcode.OperandType != OperandType.InlineType &&
61 opcode.OperandType != OperandType.InlineTok)
62 throw new ArgumentException ("opcode");
64 return FinalCreate (opcode, type);
67 public Instruction Create (OpCode opcode, MethodReference meth)
69 if (opcode.OperandType != OperandType.InlineMethod &&
70 opcode.OperandType != OperandType.InlineTok)
71 throw new ArgumentException ("opcode");
73 return FinalCreate (opcode, meth);
76 public Instruction Create (OpCode opcode, FieldReference field)
78 if (opcode.OperandType != OperandType.InlineField &&
79 opcode.OperandType != OperandType.InlineTok)
80 throw new ArgumentException ("opcode");
82 return FinalCreate (opcode, field);
85 public Instruction Create (OpCode opcode, string str)
87 if (opcode.OperandType != OperandType.InlineString)
88 throw new ArgumentException ("opcode");
90 return FinalCreate (opcode, str);
93 public Instruction Create (OpCode opcode, sbyte b)
95 if (opcode.OperandType != OperandType.ShortInlineI &&
96 opcode != OpCodes.Ldc_I4_S)
97 throw new ArgumentException ("opcode");
99 return FinalCreate (opcode, b);
102 public Instruction Create (OpCode opcode, byte b)
104 if (opcode.OperandType != OperandType.ShortInlineI ||
105 opcode == OpCodes.Ldc_I4_S)
106 throw new ArgumentException ("opcode");
108 return FinalCreate (opcode, b);
111 public Instruction Create (OpCode opcode, int i)
113 if (opcode.OperandType != OperandType.InlineI)
114 throw new ArgumentException ("opcode");
116 return FinalCreate (opcode, i);
119 public Instruction Create (OpCode opcode, long l)
121 if (opcode.OperandType != OperandType.InlineI8)
122 throw new ArgumentException ("opcode");
124 return FinalCreate (opcode, l);
127 public Instruction Create (OpCode opcode, float f)
129 if (opcode.OperandType != OperandType.ShortInlineR)
130 throw new ArgumentException ("opcode");
132 return FinalCreate (opcode, f);
135 public Instruction Create (OpCode opcode, double d)
137 if (opcode.OperandType != OperandType.InlineR)
138 throw new ArgumentException ("opcode");
140 return FinalCreate (opcode, d);
143 public Instruction Create (OpCode opcode, Instruction label)
145 if (opcode.OperandType != OperandType.InlineBrTarget &&
146 opcode.OperandType != OperandType.ShortInlineBrTarget)
147 throw new ArgumentException ("opcode");
149 return FinalCreate (opcode, label);
152 public Instruction Create (OpCode opcode, Instruction [] labels)
154 if (opcode.OperandType != OperandType.InlineSwitch)
155 throw new ArgumentException ("opcode");
157 return FinalCreate (opcode, labels);
160 public Instruction Create (OpCode opcode, VariableDefinition var)
162 if (opcode.OperandType != OperandType.ShortInlineVar &&
163 opcode.OperandType != OperandType.InlineVar)
164 throw new ArgumentException ("opcode");
166 return FinalCreate (opcode, var);
169 public Instruction Create (OpCode opcode, ParameterDefinition param)
171 if (opcode.OperandType != OperandType.ShortInlineParam &&
172 opcode.OperandType != OperandType.InlineParam)
173 throw new ArgumentException ("opcode");
175 return FinalCreate (opcode, param);
178 Instruction FinalCreate (OpCode opcode)
180 return FinalCreate (opcode, null);
183 Instruction FinalCreate (OpCode opcode, object operand)
185 return new Instruction (opcode, operand);
188 public Instruction Emit (OpCode opcode)
190 Instruction instr = Create (opcode);
195 public Instruction Emit (OpCode opcode, TypeReference type)
197 Instruction instr = Create (opcode, type);
202 public Instruction Emit (OpCode opcode, MethodReference meth)
204 Instruction instr = Create (opcode, meth);
209 public Instruction Emit (OpCode opcode, FieldReference field)
211 Instruction instr = Create (opcode, field);
216 public Instruction Emit (OpCode opcode, string str)
218 Instruction instr = Create (opcode, str);
223 public Instruction Emit (OpCode opcode, byte b)
225 Instruction instr = Create (opcode, b);
230 public Instruction Emit (OpCode opcode, sbyte b)
232 Instruction instr = Create (opcode, b);
237 public Instruction Emit (OpCode opcode, int i)
239 Instruction instr = Create (opcode, i);
244 public Instruction Emit (OpCode opcode, long l)
246 Instruction instr = Create (opcode, l);
251 public Instruction Emit (OpCode opcode, float f)
253 Instruction instr = Create (opcode, f);
258 public Instruction Emit (OpCode opcode, double d)
260 Instruction instr = Create (opcode, d);
265 public Instruction Emit (OpCode opcode, Instruction target)
267 Instruction instr = Create (opcode, target);
272 public Instruction Emit (OpCode opcode, Instruction [] targets)
274 Instruction instr = Create (opcode, targets);
279 public Instruction Emit (OpCode opcode, VariableDefinition var)
281 Instruction instr = Create (opcode, var);
286 public Instruction Emit (OpCode opcode, ParameterDefinition param)
288 Instruction instr = Create (opcode, param);
293 public void InsertBefore (Instruction target, Instruction instr)
295 int index = m_instrs.IndexOf (target);
297 throw new ArgumentOutOfRangeException ("Target instruction not in method body");
299 m_instrs.Insert (index, instr);
300 instr.Previous = target.Previous;
301 if (target.Previous != null)
302 target.Previous.Next = instr;
303 target.Previous = instr;
307 public void InsertAfter (Instruction target, Instruction instr)
309 int index = m_instrs.IndexOf (target);
311 throw new ArgumentOutOfRangeException ("Target instruction not in method body");
313 m_instrs.Insert (index + 1, instr);
314 instr.Next = target.Next;
315 if (target.Next != null)
316 target.Next.Previous = instr;
318 instr.Previous = target;
321 public void Append (Instruction instr)
323 Instruction last = null, current = instr;
324 if (m_instrs.Count > 0)
325 last = m_instrs [m_instrs.Count - 1];
329 current.Previous = last;
332 m_instrs.Add (current);
335 public void Replace (Instruction old, Instruction instr)
337 int index = m_instrs.IndexOf (old);
339 throw new ArgumentOutOfRangeException ("Target instruction not in method body");
341 InsertAfter (old, instr);
345 public void Remove (Instruction instr)
347 if (!m_instrs.Contains (instr))
348 throw new ArgumentException ("Instruction not in method body");
350 if (instr.Previous != null)
351 instr.Previous.Next = instr.Next;
352 if (instr.Next != null)
353 instr.Next.Previous = instr.Previous;
354 m_instrs.Remove (instr);