public PropertyValueReference (EvaluationContext ctx, PropertyInfoMirror property, object obj, TypeMirror declaringType, Value[] indexerArgs): base (ctx)
		{
			this.property = property;
			this.obj = obj;
			this.declaringType = declaringType;
			this.indexerArgs = indexerArgs;
			flags = ObjectValueFlags.Property;
			if (property.GetSetMethod (true) == null)
				flags |= ObjectValueFlags.ReadOnly;
			MethodMirror getter = property.GetGetMethod (true);
			if (getter.IsStatic)
				flags |= ObjectValueFlags.Global;
			if (getter.IsPublic)
				flags |= ObjectValueFlags.Public;
			else if (getter.IsPrivate)
				flags |= ObjectValueFlags.Private;
			else if (getter.IsFamily)
				flags |= ObjectValueFlags.Protected;
			else if (getter.IsFamilyAndAssembly)
				flags |= ObjectValueFlags.Internal;
			else if (getter.IsFamilyOrAssembly)
				flags |= ObjectValueFlags.InternalProtected;
			if (property.DeclaringType.IsValueType)
				flags |= ObjectValueFlags.ReadOnly; // Setting property values on structs is not supported by sdb
		}
Example #2
0
		public void SetValues (IList<FieldInfoMirror> fields, Value[] values) {
			if (fields == null)
				throw new ArgumentNullException ("fields");
			if (values == null)
				throw new ArgumentNullException ("values");
			foreach (FieldInfoMirror f in fields) {
				if (f == null)
					throw new ArgumentNullException ("field");
				CheckMirror (f);
			}
			foreach (Value v in values) {
				if (v == null)
					throw new ArgumentNullException ("values");
				CheckMirror (v);
			}
			long[] ids = new long [fields.Count];
			for (int i = 0; i < fields.Count; ++i)
				ids [i] = fields [i].Id;
			try {
				vm.conn.Object_SetValues (id, ids, vm.EncodeValues (values));
			} catch (CommandException ex) {
				if (ex.ErrorCode == ErrorCode.INVALID_FIELDID)
					throw new ArgumentException ("One of the fields is not valid for this type.", "fields");
				else if (ex.ErrorCode == ErrorCode.INVALID_ARGUMENT)
					throw new ArgumentException ("One of the values is not valid for its field.", "values");
				else
					throw;
			}
		}
		public void SetValues (int index, Value[] values) {
			if (values == null)
				throw new ArgumentNullException ("values");
			// FIXME: Multiple dimensions
			if (index < 0 || index > Length - values.Length)
				throw new IndexOutOfRangeException ();
			vm.conn.Array_SetValues (id, index, vm.EncodeValues (values));
		}
		public PropertyValueReference (EvaluationContext ctx, PropertyInfoMirror property, object obj, TypeMirror declaringType, MethodMirror getter, Value[] indexerArgs): base (ctx)
		{
			this.property = property;
			this.obj = obj;
			this.declaringType = declaringType;
			this.indexerArgs = indexerArgs;
			
			flags = GetFlags (property, getter);
		}
		Value NormalizeValue (EvaluationContext ctx, Value value)
		{
			if (variable.Type.IsPointer) {
				long addr = (long) ((PrimitiveValue) value).Value;

				return new PointerValue (value.VirtualMachine, variable.Type, addr);
			}

			return ctx.Adapter.IsNull (ctx, value) ? null : value;
		}
		public PropertyValueReference (EvaluationContext ctx, PropertyInfoMirror property, object obj, TypeMirror declaringType, MethodMirror getter, Value[] indexerArgs): base (ctx)
		{
			this.declaringType = declaringType;
			this.indexerArgs = indexerArgs;
			this.property = property;
			this.getter = getter;
			this.obj = obj;

			var objectMirror = obj as ObjectMirror;
			if (objectMirror != null)
				EnsureContextHasDomain (objectMirror.Domain);

			flags = GetFlags (property, getter);
		}
		public ObjectMirror CreateBoxedValue (Value value) {
			if (value == null)
				throw new ArgumentNullException ("value");
			if (!(value is PrimitiveValue) && !(value is StructMirror))
				throw new ArgumentException ("Value must be a PrimitiveValue or a StructMirror", "value");
			if ((value is PrimitiveValue) && (value as PrimitiveValue).Value == null)
				return null;

			TypeMirror t = null;
			if (value is PrimitiveValue)
				t = GetCorrespondingType ((value as PrimitiveValue).Value.GetType ());
			else
				t = (value as StructMirror).Type;

			return vm.GetObject<ObjectMirror> (vm.conn.Domain_CreateBoxedValue (id, t.Id, vm.EncodeValue (value)));
		}
		public void SetValue (LocalVariable var, Value value) {
			if (var == null)
				throw new ArgumentNullException ("var");
			if (var.Method != Method)
				throw new ArgumentException ("Local variable doesn't belong to this frame's method.");
			if (value == null)
				throw new ArgumentNullException ("value");
			CheckMirror (value);
			// FIXME: Liveness
			// FIXME: Check for return value
			try {
				vm.conn.StackFrame_SetValues (thread.Id, Id, new int [] { var.GetValueIndex }, new ValueImpl [] { vm.EncodeValue (value) });
			} catch (CommandException ex) {
				if (ex.ErrorCode == ErrorCode.INVALID_ARGUMENT)
					throw new ArgumentException ("Value does not match the type of the local variable.");
				else
					throw;
			}
		}
Example #9
0
		internal static Value InvokeMethod (VirtualMachine vm, ThreadMirror thread, MethodMirror method, Value this_obj, IList<Value> arguments, InvokeOptions options) {
			return EndInvokeMethodInternal (BeginInvokeMethod (vm, thread, method, this_obj, arguments, options, null, null));
		}
Example #10
0
		//
		// Implementation of InvokeMultiple
		//

		internal static IInvokeAsyncResult BeginInvokeMultiple (VirtualMachine vm, ThreadMirror thread, MethodMirror[] methods, Value this_obj, IList<IList<Value>> arguments, InvokeOptions options, AsyncCallback callback, object state) {
			if (thread == null)
				throw new ArgumentNullException ("thread");
			if (methods == null)
				throw new ArgumentNullException ("methods");
			foreach (var m in methods)
				if (m == null)
					throw new ArgumentNullException ("method");
			if (arguments == null) {
				arguments = new List<IList<Value>> ();
				for (int i = 0; i < methods.Length; ++i)
					arguments.Add (new Value [0]);
			} else {
				// FIXME: Not needed for property evaluation
				throw new NotImplementedException ();
			}
			if (callback == null)
				throw new ArgumentException ("A callback argument is required for this method.", "callback");

			InvokeFlags f = InvokeFlags.NONE;

			if ((options & InvokeOptions.DisableBreakpoints) != 0)
				f |= InvokeFlags.DISABLE_BREAKPOINTS;
			if ((options & InvokeOptions.SingleThreaded) != 0)
				f |= InvokeFlags.SINGLE_THREADED;

			InvokeAsyncResult r = new InvokeAsyncResult { AsyncState = state, AsyncWaitHandle = new ManualResetEvent (false), VM = vm, Thread = thread, Callback = callback, NumPending = methods.Length, IsMultiple = true };

			var mids = new long [methods.Length];
			for (int i = 0; i < methods.Length; ++i)
				mids [i] = methods [i].Id;
			var args = new List<ValueImpl[]> ();
			for (int i = 0; i < methods.Length; ++i)
				args.Add (vm.EncodeValues (arguments [i]));
			thread.InvalidateFrames ();
			r.ID = vm.conn.VM_BeginInvokeMethods (thread.Id, mids, this_obj != null ? vm.EncodeValue (this_obj) : vm.EncodeValue (vm.CreateValue (null)), args, f, InvokeMultipleCB, r);

			return r;
		}
Example #11
0
		public void SetValue (FieldInfoMirror field, Value value) {
			SetValues (new FieldInfoMirror [] { field }, new Value [] { value });
		}
Example #12
0
		internal static IInvokeAsyncResult BeginInvokeMethod (VirtualMachine vm, ThreadMirror thread, MethodMirror method, Value this_obj, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
			if (thread == null)
				throw new ArgumentNullException ("thread");
			if (method == null)
				throw new ArgumentNullException ("method");
			if (arguments == null)
				arguments = new Value [0];

			InvokeFlags f = InvokeFlags.NONE;

			if ((options & InvokeOptions.DisableBreakpoints) != 0)
				f |= InvokeFlags.DISABLE_BREAKPOINTS;
			if ((options & InvokeOptions.SingleThreaded) != 0)
				f |= InvokeFlags.SINGLE_THREADED;
			if ((options & InvokeOptions.ReturnOutThis) != 0)
				f |= InvokeFlags.OUT_THIS;
			if ((options & InvokeOptions.ReturnOutArgs) != 0)
				f |= InvokeFlags.OUT_ARGS;

			InvokeAsyncResult r = new InvokeAsyncResult { AsyncState = state, AsyncWaitHandle = new ManualResetEvent (false), VM = vm, Thread = thread, Callback = callback };
			thread.InvalidateFrames ();
			r.ID = vm.conn.VM_BeginInvokeMethod (thread.Id, method.Id, this_obj != null ? vm.EncodeValue (this_obj) : vm.EncodeValue (vm.CreateValue (null)), vm.EncodeValues (arguments), f, InvokeCB, r);

			return r;
		}
		public VariableValueReference (EvaluationContext ctx, string name, LocalVariable variable, Value value) : base (ctx)
		{
			this.variable = variable;
			this.value = value;
			this.name = name;
		}
		public Value RuntimeInvoke (MethodMirror method, object target, Value[] values)
		{
			if (values != null) {
				// Some arguments may need to be boxed
				var mparams = method.GetParameters ();
				if (mparams.Length != values.Length)
					throw new EvaluatorException ("Invalid number of arguments when calling: " + method.Name);
				
				for (int n = 0; n < mparams.Length; n++) {
					var tm = mparams[n].ParameterType;
					if (tm.IsValueType || tm.IsPrimitive)
						continue;

					var type = Adapter.GetValueType (this, values[n]);
					var argTypeMirror = type as TypeMirror;
					var argType = type as Type;

					if (IsValueTypeOrPrimitive (argTypeMirror) || IsValueTypeOrPrimitive (argType)) {
						// A value type being assigned to a parameter which is not a value type. The value has to be boxed.
						try {
							values[n] = Thread.Domain.CreateBoxedValue (values [n]);
						} catch (NotSupportedException) {
							// This runtime doesn't support creating boxed values
							throw new EvaluatorException ("This runtime does not support creating boxed values.");
						}
					}
				}
			}

			if (!method.IsStatic && method.DeclaringType.IsClass && !IsValueTypeOrPrimitive (method.DeclaringType)) {
				object type = Adapter.GetValueType (this, target);
				var targetTypeMirror = type as TypeMirror;
				var targetType = type as Type;

				if ((target is StructMirror && ((StructMirror) target).Type != method.DeclaringType) ||
				    (IsValueTypeOrPrimitive (targetTypeMirror) || IsValueTypeOrPrimitive (targetType))) {
					// A value type being assigned to a parameter which is not a value type. The value has to be boxed.
					try {
						target = Thread.Domain.CreateBoxedValue ((Value) target);
					} catch (NotSupportedException) {
						// This runtime doesn't support creating boxed values
						throw new EvaluatorException ("This runtime does not support creating boxed values.");
					}
				}
			}

			try {
				return method.Evaluate (target is TypeMirror ? null : (Value) target, values);
			} catch (NotSupportedException) {
				AssertTargetInvokeAllowed ();

				var mc = new MethodCall (this, method, target, values);
				Adapter.AsyncExecute (mc, Options.EvaluationTimeout);

				return mc.ReturnValue;
			}
		}
 public Value RuntimeInvoke(MethodMirror method, object target, Value[] values, out Value[] outArgs)
 {
     return RuntimeInvoke (method, target, values, true, out outArgs);
 }
Example #16
0
		// Since protocol version 2.44
		public void SetThis (Value value) {
			if (value == null)
				throw new ArgumentNullException ("value");
			if (Method.IsStatic || !Method.DeclaringType.IsValueType)
				throw new InvalidOperationException ("The frame's method needs to be a valuetype instance method.");
			vm.conn.StackFrame_SetThis (thread.Id, Id, vm.EncodeValue (value));
		}
Example #17
0
		internal EnumMirror (VirtualMachine vm, TypeMirror type, Value[] fields) : base (vm, type, fields) {
		}
Example #18
0
		public Value Evaluate (Value this_val, Value[] args) {
			var body = method.GetMethodBody ();

			// Implement only the IL opcodes required to evaluate mcs compiled property accessors:
			// IL_0000:  nop
			// IL_0001:  ldarg.0
			// IL_0002:  ldfld      int32 Tests::field_i
			// IL_0007:  stloc.0
			// IL_0008:  br         IL_000d
			// IL_000d:  ldloc.0
			// IL_000e:  ret
			if (args != null && args.Length != 0)
				throw new NotSupportedException ();				
			if (method.IsStatic || method.DeclaringType.IsValueType || this_val == null || !(this_val is ObjectMirror))
				throw new NotSupportedException ();

			var instructions = body.Instructions;
			if (instructions.Count > 16)
				throw new NotSupportedException ();

			Value[] stack = new Value [16];
			Value locals_0 = null;
			Value res = null;

			int sp = 0;
			int ins_count = 0;
			var ins = instructions [0];
			while (ins != null) {
				if (ins_count > 16)
					throw new NotImplementedException ();
				ins_count ++;
				var next = ins.Next;

				var op = ins.OpCode;
				if (op == OpCodes.Nop) {
				} else if (op == OpCodes.Ldarg_0) {
					if (sp > 0)
						throw new NotSupportedException ();
					stack [sp++] = this_val;
				} else if (op == OpCodes.Ldfld) {
					if (sp != 1)
						throw new NotSupportedException ();
					var obj = (ObjectMirror)stack [--sp];
					var field = (FieldInfoMirror)ins.Operand;
					stack [sp++] = obj.GetValue (field);
				} else if (op == OpCodes.Stloc_0) {
					if (sp != 1)
						throw new NotSupportedException ();
					locals_0 = stack [--sp];
				} else if (op == OpCodes.Br) {
					next = (ILInstruction)ins.Operand;
				} else if (op == OpCodes.Ldloc_0) {
					if (sp != 0)
						throw new NotSupportedException ();
					stack [sp++] = locals_0;
				} else if (op == OpCodes.Ret) {
					if (sp == 0)
						res = null;
					else
						res = stack [--sp];
					break;
				}
				ins = next;
			}

			return res;
		}
		public void SetValue (ParameterInfoMirror param, Value value) {
			if (param == null)
				throw new ArgumentNullException ("param");
			if (param.Method != Method)
				throw new ArgumentException ("Parameter doesn't belong to this frame's method.");
			if (param.IsRetval)
				throw new ArgumentException ("Parameter represents the method return value.");
			if (value == null)
				throw new ArgumentNullException ("value");
			CheckMirror (value);

			// FIXME: Liveness
			// FIXME: Allow setting the frame return value if possible
			try {
				vm.conn.StackFrame_SetValues (thread.Id, Id, new int [] { (- param.Position) - 1 }, new ValueImpl [] { vm.EncodeValue (value) });
			} catch (CommandException ex) {
				if (ex.ErrorCode == ErrorCode.INVALID_ARGUMENT)
					throw new ArgumentException ("Value does not match the type of the variable.");
				else
					throw;
			}
		}
Example #20
0
 public SdbValue(MDS.Value value) :
     base(value)
 {
 }
Example #21
0
		internal void SetField (int index, Value value) {
			fields [index] = value;
		}
Example #22
0
		internal void SetFields (Value[] fields) {
			this.fields = fields;
		}
Example #23
0
		internal StructMirror (VirtualMachine vm, TypeMirror type, Value[] fields) : base (vm, 0) {
			this.type = type;
			this.fields = fields;
		}
		public override void SetValue (EvaluationContext ctx, object value)
		{
			ctx.AssertTargetInvokeAllowed ();

			var args = new Value [indexerArgs != null ? indexerArgs.Length + 1 : 1];
			if (indexerArgs != null)
				indexerArgs.CopyTo (args, 0);

			args [args.Length - 1] = (Value) value;

			var setter = property.GetSetMethod (true);
			if (setter == null)
				throw new EvaluatorException ("Property is read-only");

			this.value = null;
			haveValue = false;

			((SoftEvaluationContext) ctx).RuntimeInvoke (setter, obj ?? declaringType, args);

			this.value = value;
			haveValue = true;
		}
        //
        // Evaluate the method on the client using an IL interpreter.
        // Only supports a subset of IL instructions. Doesn't change
        // debuggee state.
        // Returns the result of the evaluation, or null for methods
        // which return void.
        // Throws a NotSupportedException if the method body contains
        // unsupported IL instructions, or if evaluating the method
        // would change debuggee state.
        //
        public Value Evaluate(Value this_val, Value[] args)
        {
            var interp = new ILInterpreter (this);

            return interp.Evaluate (this_val, args);
        }
		public Value RuntimeInvoke (MethodMirror method, object target, Value[] values)
		{
			if (values != null) {
				// Some arguments may need to be boxed
				ParameterInfoMirror[] mparams = method.GetParameters ();
				if (mparams.Length != values.Length)
					throw new EvaluatorException ("Invalid number of arguments when calling: " + method.Name);
				
				for (int n=0; n<mparams.Length; n++) {
					TypeMirror tm = mparams [n].ParameterType;
					if (tm.IsValueType || tm.IsPrimitive)
						continue;
					object type = Adapter.GetValueType (this, values [n]);
					TypeMirror argTypeMirror = type as TypeMirror;
					Type argType = type as Type;
					if ((argTypeMirror != null && (argTypeMirror.IsValueType || argTypeMirror.IsPrimitive)) || (argType != null && (argType.IsValueType || argType.IsPrimitive))) {
						// A value type being assigned to a parameter which is not a value type. The value has to be boxed.
						try {
							values [n] = Thread.Domain.CreateBoxedValue (values [n]);
						} catch (NotSupportedException) {
							// This runtime doesn't support creating boxed values
							break;
						}
					}
				}
			}			
			MethodCall mc = new MethodCall (this, method, target, values);
			Adapter.AsyncExecute (mc, Options.EvaluationTimeout);
			return mc.ReturnValue;
		}
Example #27
0
		public Value Evaluate (Value this_val, Value[] args) {
			var body = method.GetMethodBody ();

			// Implement only the IL opcodes required to evaluate mcs compiled property accessors:
			// IL_0000:  nop
			// IL_0001:  ldarg.0
			// IL_0002:  ldfld      int32 Tests::field_i
			// IL_0007:  stloc.0
			// IL_0008:  br         IL_000d
			// IL_000d:  ldloc.0
			// IL_000e:  ret
			// ... or returns a simple constant:
			// IL_0000:  ldc.i4 1024
			// IL_0005:  conv.i8
			// IL_0006:  ret
			if (args != null && args.Length != 0)
				throw new NotSupportedException ();

			if (method.IsStatic || method.DeclaringType.IsValueType || this_val == null || !(this_val is ObjectMirror))
				throw new NotSupportedException ();

			var instructions = body.Instructions;
			if (instructions.Count < 1 || instructions.Count > 16)
				throw new NotSupportedException ();

			var stack = new Value [16];
			var ins = instructions [0];
			Value locals_0 = null;
			int ins_count = 0;
			int sp = 0;

			while (ins != null) {
				if (ins_count > 16)
					throw new NotImplementedException ();

				var next = ins.Next;
				ins_count++;

				var op = ins.OpCode;
				if (op == OpCodes.Nop) {
				} else if (op == OpCodes.Ldarg_0) {
					if (sp != 0)
						throw new NotSupportedException ();

					stack [sp++] = this_val;
				} else if (op == OpCodes.Ldfld) {
					if (sp != 1)
						throw new NotSupportedException ();

					var obj = (ObjectMirror) stack [--sp];
					var field = (FieldInfoMirror) ins.Operand;
					try {
						stack [sp++] = obj.GetValue (field);
					} catch (ArgumentException) {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Ldc_I4_0) {
					if (sp != 0)
						throw new NotSupportedException ();

					try {
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, 0);
					} catch (ArgumentException) {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Ldc_I4_1) {
					if (sp != 0)
						throw new NotSupportedException ();

					try {
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, 1);
					} catch (ArgumentException) {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Ldc_I4_2) {
					if (sp != 0)
						throw new NotSupportedException ();

					try {
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, 2);
					} catch (ArgumentException) {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Ldc_I4_3) {
					if (sp != 0)
						throw new NotSupportedException ();

					try {
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, 3);
					} catch (ArgumentException) {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Ldc_I4_4) {
					if (sp != 0)
						throw new NotSupportedException ();

					try {
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, 4);
					} catch (ArgumentException) {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Ldc_I4_5) {
					if (sp != 0)
						throw new NotSupportedException ();

					try {
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, 5);
					} catch (ArgumentException) {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Ldc_I4_6) {
					if (sp != 0)
						throw new NotSupportedException ();

					try {
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, 6);
					} catch (ArgumentException) {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Ldc_I4_7) {
					if (sp != 0)
						throw new NotSupportedException ();

					try {
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, 7);
					} catch (ArgumentException) {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Ldc_I4_8) {
					if (sp != 0)
						throw new NotSupportedException ();

					try {
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, 8);
					} catch (ArgumentException) {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Ldc_I4_M1) {
					if (sp != 0)
						throw new NotSupportedException ();

					try {
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, -1);
					} catch (ArgumentException) {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Ldc_I4) {
					if (sp != 0)
						throw new NotSupportedException ();

					try {
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand);
					} catch (ArgumentException) {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Ldc_I4_S) {
					if (sp != 0)
						throw new NotSupportedException ();

					try {
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand);
					} catch (ArgumentException) {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Ldc_I8) {
					if (sp != 0)
						throw new NotSupportedException ();

					try {
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand);
					} catch (ArgumentException) {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Ldc_R4) {
					if (sp != 0)
						throw new NotSupportedException ();

					try {
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand);
					} catch (ArgumentException) {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Ldc_R8) {
					if (sp != 0)
						throw new NotSupportedException ();

					try {
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand);
					} catch (ArgumentException) {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Conv_I) {
					if (sp != 1)
						throw new NotSupportedException ();

					try {
						var primitive = (PrimitiveValue) stack [--sp];
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToInt32 (primitive.Value));
					} catch {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Conv_I1) {
					if (sp != 1)
						throw new NotSupportedException ();

					try {
						var primitive = (PrimitiveValue) stack [--sp];
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToSByte (primitive.Value));
					} catch {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Conv_U1) {
					if (sp != 1)
						throw new NotSupportedException ();

					try {
						var primitive = (PrimitiveValue) stack [--sp];
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToByte (primitive.Value));
					} catch {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Conv_I2) {
					if (sp != 1)
						throw new NotSupportedException ();

					try {
						var primitive = (PrimitiveValue) stack [--sp];
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToInt16 (primitive.Value));
					} catch {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Conv_U2) {
					if (sp != 1)
						throw new NotSupportedException ();

					try {
						var primitive = (PrimitiveValue) stack [--sp];
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt16 (primitive.Value));
					} catch {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Conv_I4) {
					if (sp != 1)
						throw new NotSupportedException ();

					try {
						var primitive = (PrimitiveValue) stack [--sp];
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToInt32 (primitive.Value));
					} catch {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Conv_U4) {
					if (sp != 1)
						throw new NotSupportedException ();

					try {
						var primitive = (PrimitiveValue) stack [--sp];
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt32 (primitive.Value));
					} catch {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Conv_I8) {
					if (sp != 1)
						throw new NotSupportedException ();

					try {
						var primitive = (PrimitiveValue) stack [--sp];
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToInt64 (primitive.Value));
					} catch {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Conv_U8) {
					if (sp != 1)
						throw new NotSupportedException ();

					try {
						var primitive = (PrimitiveValue) stack [--sp];
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt64 (primitive.Value));
					} catch {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Conv_R4) {
					if (sp != 1)
						throw new NotSupportedException ();

					try {
						var primitive = (PrimitiveValue) stack [--sp];
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToSingle (primitive.Value));
					} catch {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Conv_R8) {
					if (sp != 1)
						throw new NotSupportedException ();

					try {
						var primitive = (PrimitiveValue) stack [--sp];
						stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToDouble (primitive.Value));
					} catch {
						throw new NotSupportedException ();
					}
				} else if (op == OpCodes.Stloc_0) {
					if (sp != 1)
						throw new NotSupportedException ();

					locals_0 = stack [--sp];
				} else if (op == OpCodes.Br || op == OpCodes.Br_S) {
					next = (ILInstruction) ins.Operand;
				} else if (op == OpCodes.Ldloc_0) {
					if (sp != 0)
						throw new NotSupportedException ();

					stack [sp++] = locals_0;
				} else if (op == OpCodes.Ret) {
					if (sp > 0) {
						var res = stack [--sp];

						var primitive = res as PrimitiveValue;
						if (method.ReturnType.IsPrimitive && primitive != null) {
							// cast the primitive value to the return type
							try {
								switch (method.ReturnType.CSharpName) {
								case "double": res = new PrimitiveValue (method.VirtualMachine, Convert.ToDouble (primitive.Value)); break;
								case "float": res = new PrimitiveValue (method.VirtualMachine, Convert.ToSingle (primitive.Value)); break;
								case "ulong": res = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt64 (primitive.Value)); break;
								case "long": res = new PrimitiveValue (method.VirtualMachine, Convert.ToInt64 (primitive.Value)); break;
								case "uint": res = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt32 (primitive.Value)); break;
								case "int": res = new PrimitiveValue (method.VirtualMachine, Convert.ToInt32 (primitive.Value)); break;
								case "ushort": res = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt16 (primitive.Value)); break;
								case "short": res = new PrimitiveValue (method.VirtualMachine, Convert.ToInt16 (primitive.Value)); break;
								case "sbyte": res = new PrimitiveValue (method.VirtualMachine, Convert.ToSByte (primitive.Value)); break;
								case "byte": res = new PrimitiveValue (method.VirtualMachine, Convert.ToByte (primitive.Value)); break;
								case "char": res = new PrimitiveValue (method.VirtualMachine, Convert.ToChar (primitive.Value)); break;
								case "bool": res = new PrimitiveValue (method.VirtualMachine, Convert.ToBoolean (primitive.Value)); break;
								}
							} catch {
								throw new NotSupportedException ();
							}
						}

						return res;
					}

					return null;
				} else {
					throw new NotSupportedException ();
				}

				ins = next;
			}

			return null;
		}