+ CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Incompatible type %s in field store at 0x%04x", type_names [UNMASK_TYPE (value->stype)], ctx->ip_offset));
+}
+
+/*TODO proper handle for Nullable<T>*/
+static void
+do_box_value (VerifyContext *ctx, int klass_token)
+{
+ ILStackDesc *value;
+ MonoType *type = get_boxable_mono_type (ctx, klass_token);
+
+ if (!type)
+ return;
+
+ if (!check_underflow (ctx, 1))
+ return;
+
+ value = stack_top (ctx);
+ /*box is a nop for reference types*/
+ if (value->stype == TYPE_COMPLEX && MONO_TYPE_IS_REFERENCE (value->type) && MONO_TYPE_IS_REFERENCE (type))
+ return;
+
+ value = stack_pop (ctx);
+
+ if (!verify_type_compat (ctx, type, value))
+ CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid type at stack for boxing operation at 0x%04x", ctx->ip_offset));
+
+ stack_push_val (ctx, TYPE_COMPLEX, mono_class_get_type (mono_defaults.object_class));
+}
+
+static void
+do_unbox_value (VerifyContext *ctx, int klass_token)
+{
+ ILStackDesc *value;
+ MonoType *type = get_boxable_mono_type (ctx, klass_token);
+
+ if (!type)
+ return;
+
+ if (!check_underflow (ctx, 1))
+ return;
+
+ value = stack_pop (ctx);
+
+ if (value->stype != TYPE_COMPLEX || value->type->type != MONO_TYPE_OBJECT)
+ CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid type %s at stack for unbox operation at 0x%04x", type_names [UNMASK_TYPE (value->stype)], ctx->ip_offset));
+
+ //TODO Pushed managed pointer is haver controled mutability (CMMP)
+ set_stack_value (stack_push (ctx), mono_type_get_type_byref (type), FALSE);
+}
+
+static void
+do_unary_math_op (VerifyContext *ctx, int op)
+{
+ ILStackDesc *value;
+ if (!check_underflow (ctx, 1))
+ return;
+ value = stack_top (ctx);
+ switch(value->stype) {
+ case TYPE_I4:
+ case TYPE_I8:
+ case TYPE_NATIVE_INT:
+ break;
+ case TYPE_R8:
+ if (op == CEE_NEG)
+ break;
+ case TYPE_COMPLEX: /*only enums are ok*/
+ if (value->type->type == MONO_TYPE_VALUETYPE && value->type->data.klass->enumtype)
+ break;
+ default:
+ CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid type at stack for unary not at 0x%04x", ctx->ip_offset));
+ }
+}
+
+static void
+do_conversion (VerifyContext *ctx, int kind)
+{
+ ILStackDesc *value;
+ if (!check_underflow (ctx, 1))
+ return;
+ value = stack_pop (ctx);
+
+ switch(value->stype) {
+ case TYPE_I4:
+ case TYPE_I8:
+ case TYPE_NATIVE_INT:
+ case TYPE_R8:
+ break;
+ default:
+ CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid type at stack for conversion operation at 0x%04x", ctx->ip_offset));
+ }
+
+ switch (kind) {
+ case TYPE_I4:
+ stack_push_val (ctx, TYPE_I4, &mono_defaults.int32_class->byval_arg);
+ break;
+ case TYPE_I8:
+ stack_push_val (ctx,TYPE_I8, &mono_defaults.int64_class->byval_arg);
+ break;
+ case TYPE_R8:
+ stack_push_val (ctx, TYPE_R8, &mono_defaults.double_class->byval_arg);
+ break;
+ case TYPE_NATIVE_INT:
+ stack_push_val (ctx, TYPE_NATIVE_INT, &mono_defaults.int_class->byval_arg);
+ break;
+ default:
+ g_error ("unknown type %02x in conversion", kind);
+
+ }
+}
+
+static void
+do_load_token (VerifyContext *ctx, int token)
+{
+ gpointer handle;
+ MonoClass *handle_class;
+ if (!check_overflow (ctx))
+ return;
+ handle = mono_ldtoken (ctx->image, token, &handle_class, ctx->generic_context);
+ if (!handle) {
+ ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Invalid token 0x%x for ldtoken at 0x%04x", token, ctx->ip_offset));
+ return;
+ }
+ stack_push_val (ctx, TYPE_COMPLEX, mono_class_get_type (handle_class));
+}
+
+static void
+do_ldobj_value (VerifyContext *ctx, int token)
+{
+ ILStackDesc *value;
+ MonoType *type = get_boxable_mono_type (ctx, token);
+
+ if (!type)
+ return;
+
+ if (!check_underflow (ctx, 1))
+ return;
+
+ value = stack_pop (ctx);
+ if (!IS_MANAGED_POINTER (value->stype)
+ && value->stype != TYPE_NATIVE_INT
+ && !(value->stype == TYPE_PTR && value->type->type != MONO_TYPE_FNPTR)) {
+ ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Invalid argument %s to ldobj at 0x%04x", type_names [UNMASK_TYPE (value->stype)], ctx->ip_offset));
+ return;
+ }
+
+ if (value->stype == TYPE_NATIVE_INT)
+ CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Using native pointer to ldobj at 0x%04x", ctx->ip_offset));
+
+ /*We have a byval on the stack, we */
+ if (!verify_stack_type_compatibility (ctx, type, mono_type_get_type_byval (value->type), TRUE))
+ CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid type at stack for ldojb operation at 0x%04x", ctx->ip_offset));
+
+ set_stack_value (stack_push (ctx), type, FALSE);
+}
+
+static void
+do_newarr (VerifyContext *ctx, int token)
+{
+ ILStackDesc *value;
+ MonoType *type = get_boxable_mono_type (ctx, token);
+
+ if (!type)
+ return;
+
+ if (!check_underflow (ctx, 1))
+ return;
+
+ value = stack_pop (ctx);
+ if (value->stype != TYPE_I4 && value->stype != TYPE_NATIVE_INT)
+ CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Array size type on stack (%s) is not a verifiable type at 0x%04x", type_names [UNMASK_TYPE (value->stype)], ctx->ip_offset));
+
+ set_stack_value (stack_push (ctx), mono_class_get_type (mono_array_class_get (mono_class_from_mono_type (type), 1)), FALSE);