Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.ExtLibs/HeuristicLab.Cecil/0.9.5/Mono.Cecil-0.9.5/Mono.Cecil/Mono.Cecil.Cil/Instruction.cs

Last change on this file was 11700, checked in by jkarder, 10 years ago

#2077: created branch and added first version

File size: 8.5 KB
Line 
1//
2// Instruction.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
29using System;
30using System.Text;
31
32namespace Mono.Cecil.Cil {
33
34  public sealed class Instruction {
35
36    internal int offset;
37    internal OpCode opcode;
38    internal object operand;
39
40    internal Instruction previous;
41    internal Instruction next;
42
43    SequencePoint sequence_point;
44
45    public int Offset {
46      get { return offset; }
47      set { offset = value; }
48    }
49
50    public OpCode OpCode {
51      get { return opcode; }
52      set { opcode = value; }
53    }
54
55    public object Operand {
56      get { return operand; }
57      set { operand = value; }
58    }
59
60    public Instruction Previous {
61      get { return previous; }
62      set { previous = value; }
63    }
64
65    public Instruction Next {
66      get { return next; }
67      set { next = value; }
68    }
69
70    public SequencePoint SequencePoint {
71      get { return sequence_point; }
72      set { sequence_point = value; }
73    }
74
75    internal Instruction (int offset, OpCode opCode)
76    {
77      this.offset = offset;
78      this.opcode = opCode;
79    }
80
81    internal Instruction (OpCode opcode, object operand)
82    {
83      this.opcode = opcode;
84      this.operand = operand;
85    }
86
87    public int GetSize ()
88    {
89      int size = opcode.Size;
90
91      switch (opcode.OperandType) {
92      case OperandType.InlineSwitch:
93        return size + (1 + ((Instruction []) operand).Length) * 4;
94      case OperandType.InlineI8:
95      case OperandType.InlineR:
96        return size + 8;
97      case OperandType.InlineBrTarget:
98      case OperandType.InlineField:
99      case OperandType.InlineI:
100      case OperandType.InlineMethod:
101      case OperandType.InlineString:
102      case OperandType.InlineTok:
103      case OperandType.InlineType:
104      case OperandType.ShortInlineR:
105      case OperandType.InlineSig:
106        return size + 4;
107      case OperandType.InlineArg:
108      case OperandType.InlineVar:
109        return size + 2;
110      case OperandType.ShortInlineBrTarget:
111      case OperandType.ShortInlineI:
112      case OperandType.ShortInlineArg:
113      case OperandType.ShortInlineVar:
114        return size + 1;
115      default:
116        return size;
117      }
118    }
119
120    public override string ToString ()
121    {
122      var instruction = new StringBuilder ();
123
124      AppendLabel (instruction, this);
125      instruction.Append (':');
126      instruction.Append (' ');
127      instruction.Append (opcode.Name);
128
129      if (operand == null)
130        return instruction.ToString ();
131
132      instruction.Append (' ');
133
134      switch (opcode.OperandType) {
135      case OperandType.ShortInlineBrTarget:
136      case OperandType.InlineBrTarget:
137        AppendLabel (instruction, (Instruction) operand);
138        break;
139      case OperandType.InlineSwitch:
140        var labels = (Instruction []) operand;
141        for (int i = 0; i < labels.Length; i++) {
142          if (i > 0)
143            instruction.Append (',');
144
145          AppendLabel (instruction, labels [i]);
146        }
147        break;
148      case OperandType.InlineString:
149        instruction.Append ('\"');
150        instruction.Append (operand);
151        instruction.Append ('\"');
152        break;
153      default:
154        instruction.Append (operand);
155        break;
156      }
157
158      return instruction.ToString ();
159    }
160
161    static void AppendLabel (StringBuilder builder, Instruction instruction)
162    {
163      builder.Append ("IL_");
164      builder.Append (instruction.offset.ToString ("x4"));
165    }
166
167    public static Instruction Create (OpCode opcode)
168    {
169      if (opcode.OperandType != OperandType.InlineNone)
170        throw new ArgumentException ("opcode");
171
172      return new Instruction (opcode, null);
173    }
174
175    public static Instruction Create (OpCode opcode, TypeReference type)
176    {
177      if (type == null)
178        throw new ArgumentNullException ("type");
179      if (opcode.OperandType != OperandType.InlineType &&
180        opcode.OperandType != OperandType.InlineTok)
181        throw new ArgumentException ("opcode");
182
183      return new Instruction (opcode, type);
184    }
185
186    public static Instruction Create (OpCode opcode, CallSite site)
187    {
188      if (site == null)
189        throw new ArgumentNullException ("site");
190      if (opcode.Code != Code.Calli)
191        throw new ArgumentException ("code");
192
193      return new Instruction (opcode, site);
194    }
195
196    public static Instruction Create (OpCode opcode, MethodReference method)
197    {
198      if (method == null)
199        throw new ArgumentNullException ("method");
200      if (opcode.OperandType != OperandType.InlineMethod &&
201        opcode.OperandType != OperandType.InlineTok)
202        throw new ArgumentException ("opcode");
203
204      return new Instruction (opcode, method);
205    }
206
207    public static Instruction Create (OpCode opcode, FieldReference field)
208    {
209      if (field == null)
210        throw new ArgumentNullException ("field");
211      if (opcode.OperandType != OperandType.InlineField &&
212        opcode.OperandType != OperandType.InlineTok)
213        throw new ArgumentException ("opcode");
214
215      return new Instruction (opcode, field);
216    }
217
218    public static Instruction Create (OpCode opcode, string value)
219    {
220      if (value == null)
221        throw new ArgumentNullException ("value");
222      if (opcode.OperandType != OperandType.InlineString)
223        throw new ArgumentException ("opcode");
224
225      return new Instruction (opcode, value);
226    }
227
228    public static Instruction Create (OpCode opcode, sbyte value)
229    {
230      if (opcode.OperandType != OperandType.ShortInlineI &&
231        opcode != OpCodes.Ldc_I4_S)
232        throw new ArgumentException ("opcode");
233
234      return new Instruction (opcode, value);
235    }
236
237    public static Instruction Create (OpCode opcode, byte value)
238    {
239      if (opcode.OperandType != OperandType.ShortInlineI ||
240        opcode == OpCodes.Ldc_I4_S)
241        throw new ArgumentException ("opcode");
242
243      return new Instruction (opcode, value);
244    }
245
246    public static Instruction Create (OpCode opcode, int value)
247    {
248      if (opcode.OperandType != OperandType.InlineI)
249        throw new ArgumentException ("opcode");
250
251      return new Instruction (opcode, value);
252    }
253
254    public static Instruction Create (OpCode opcode, long value)
255    {
256      if (opcode.OperandType != OperandType.InlineI8)
257        throw new ArgumentException ("opcode");
258
259      return new Instruction (opcode, value);
260    }
261
262    public static Instruction Create (OpCode opcode, float value)
263    {
264      if (opcode.OperandType != OperandType.ShortInlineR)
265        throw new ArgumentException ("opcode");
266
267      return new Instruction (opcode, value);
268    }
269
270    public static Instruction Create (OpCode opcode, double value)
271    {
272      if (opcode.OperandType != OperandType.InlineR)
273        throw new ArgumentException ("opcode");
274
275      return new Instruction (opcode, value);
276    }
277
278    public static Instruction Create (OpCode opcode, Instruction target)
279    {
280      if (target == null)
281        throw new ArgumentNullException ("target");
282      if (opcode.OperandType != OperandType.InlineBrTarget &&
283        opcode.OperandType != OperandType.ShortInlineBrTarget)
284        throw new ArgumentException ("opcode");
285
286      return new Instruction (opcode, target);
287    }
288
289    public static Instruction Create (OpCode opcode, Instruction [] targets)
290    {
291      if (targets == null)
292        throw new ArgumentNullException ("targets");
293      if (opcode.OperandType != OperandType.InlineSwitch)
294        throw new ArgumentException ("opcode");
295
296      return new Instruction (opcode, targets);
297    }
298
299    public static Instruction Create (OpCode opcode, VariableDefinition variable)
300    {
301      if (variable == null)
302        throw new ArgumentNullException ("variable");
303      if (opcode.OperandType != OperandType.ShortInlineVar &&
304        opcode.OperandType != OperandType.InlineVar)
305        throw new ArgumentException ("opcode");
306
307      return new Instruction (opcode, variable);
308    }
309
310    public static Instruction Create (OpCode opcode, ParameterDefinition parameter)
311    {
312      if (parameter == null)
313        throw new ArgumentNullException ("parameter");
314      if (opcode.OperandType != OperandType.ShortInlineArg &&
315        opcode.OperandType != OperandType.InlineArg)
316        throw new ArgumentException ("opcode");
317
318      return new Instruction (opcode, parameter);
319    }
320  }
321}
Note: See TracBrowser for help on using the repository browser.