PageRenderTime 32ms CodeModel.GetById 12ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

/Mono.Cecil.Cil/Instruction.cs

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