Add --debug=casts support for ArrayTypeMismatchException's.
authorZoltan Varga <vargaz@gmail.com>
Thu, 7 Oct 2010 17:21:27 +0000 (19:21 +0200)
committerZoltan Varga <vargaz@gmail.com>
Thu, 7 Oct 2010 17:22:07 +0000 (19:22 +0200)
mono/mini/method-to-ir.c
mono/mini/mini-exceptions.c

index 1a02b15686a075f5e33b9e91c56210547b623dd8..4272f9c6de5c55874ce39d87c581611db9c3c2b0 100644 (file)
@@ -3004,6 +3004,43 @@ emit_generic_class_init (MonoCompile *cfg, MonoClass *klass)
 #endif
 }
 
+static void
+save_cast_details (MonoCompile *cfg, MonoClass *klass, int obj_reg)
+{
+       if (mini_get_debug_options ()->better_cast_details) {
+               int to_klass_reg = alloc_preg (cfg);
+               int vtable_reg = alloc_preg (cfg);
+               int klass_reg = alloc_preg (cfg);
+               MonoInst *tls_get = mono_get_jit_tls_intrinsic (cfg);
+
+               if (!tls_get) {
+                       fprintf (stderr, "error: --debug=casts not supported on this platform.\n.");
+                       exit (1);
+               }
+
+               MONO_ADD_INS (cfg->cbb, tls_get);
+               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, vtable_reg, obj_reg, G_STRUCT_OFFSET (MonoObject, vtable));
+               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, klass_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass));
+
+               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, tls_get->dreg, G_STRUCT_OFFSET (MonoJitTlsData, class_cast_from), klass_reg);
+               MONO_EMIT_NEW_PCONST (cfg, to_klass_reg, klass);
+               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, tls_get->dreg, G_STRUCT_OFFSET (MonoJitTlsData, class_cast_to), to_klass_reg);
+       }
+}
+
+static void
+reset_cast_details (MonoCompile *cfg)
+{
+       /* Reset the variables holding the cast details */
+       if (mini_get_debug_options ()->better_cast_details) {
+               MonoInst *tls_get = mono_get_jit_tls_intrinsic (cfg);
+
+               MONO_ADD_INS (cfg->cbb, tls_get);
+               /* It is enough to reset the from field */
+               MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STORE_MEMBASE_IMM, tls_get->dreg, G_STRUCT_OFFSET (MonoJitTlsData, class_cast_from), 0);
+       }
+}
+
 /*
  * On return the caller must check @array_class for load errors
  */
@@ -3016,8 +3053,10 @@ mini_emit_check_array_type (MonoCompile *cfg, MonoInst *obj, MonoClass *array_cl
        if (cfg->generic_sharing_context)
                context_used = mono_class_check_context_used (array_class);
 
+       save_cast_details (cfg, array_class, obj->dreg);
+
        MONO_EMIT_NEW_LOAD_MEMBASE_FAULT (cfg, vtable_reg, obj->dreg, G_STRUCT_OFFSET (MonoObject, vtable));
-                                      
+
        if (cfg->opt & MONO_OPT_SHARED) {
                int class_reg = alloc_preg (cfg);
                MONO_EMIT_NEW_LOAD_MEMBASE (cfg, class_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass));
@@ -3052,43 +3091,8 @@ mini_emit_check_array_type (MonoCompile *cfg, MonoInst *obj, MonoClass *array_cl
        }
        
        MONO_EMIT_NEW_COND_EXC (cfg, NE_UN, "ArrayTypeMismatchException");
-}
-
-static void
-save_cast_details (MonoCompile *cfg, MonoClass *klass, int obj_reg)
-{
-       if (mini_get_debug_options ()->better_cast_details) {
-               int to_klass_reg = alloc_preg (cfg);
-               int vtable_reg = alloc_preg (cfg);
-               int klass_reg = alloc_preg (cfg);
-               MonoInst *tls_get = mono_get_jit_tls_intrinsic (cfg);
-
-               if (!tls_get) {
-                       fprintf (stderr, "error: --debug=casts not supported on this platform.\n.");
-                       exit (1);
-               }
-
-               MONO_ADD_INS (cfg->cbb, tls_get);
-               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, vtable_reg, obj_reg, G_STRUCT_OFFSET (MonoObject, vtable));
-               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, klass_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass));
-
-               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, tls_get->dreg, G_STRUCT_OFFSET (MonoJitTlsData, class_cast_from), klass_reg);
-               MONO_EMIT_NEW_PCONST (cfg, to_klass_reg, klass);
-               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, tls_get->dreg, G_STRUCT_OFFSET (MonoJitTlsData, class_cast_to), to_klass_reg);
-       }
-}
 
-static void
-reset_cast_details (MonoCompile *cfg)
-{
-       /* Reset the variables holding the cast details */
-       if (mini_get_debug_options ()->better_cast_details) {
-               MonoInst *tls_get = mono_get_jit_tls_intrinsic (cfg);
-
-               MONO_ADD_INS (cfg->cbb, tls_get);
-               /* It is enough to reset the from field */
-               MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STORE_MEMBASE_IMM, tls_get->dreg, G_STRUCT_OFFSET (MonoJitTlsData, class_cast_from), 0);
-       }
+       reset_cast_details (cfg);
 }
 
 /**
index 934f9ab53836f5b5971265bef9ce0f32fce0aa68..f4d1e1af684fe38bd2f3856c472480b102997199 100644 (file)
@@ -1243,14 +1243,25 @@ mono_handle_exception_internal (MonoContext *ctx, gpointer obj, gpointer origina
                mono_ex = NULL;
        }
 
-       if (mono_ex && jit_tls->class_cast_from && !strcmp (mono_ex->object.vtable->klass->name, "InvalidCastException")) {
-               char *from_name = mono_type_get_full_name (jit_tls->class_cast_from);
-               char *to_name = mono_type_get_full_name (jit_tls->class_cast_to);
-               char *msg = g_strdup_printf ("Unable to cast object of type '%s' to type '%s'.", from_name, to_name);
-               mono_ex->message = mono_string_new (domain, msg);
-               g_free (from_name);
-               g_free (to_name);
-               g_free (msg);
+       if (mono_ex && jit_tls->class_cast_from) {
+               if (!strcmp (mono_ex->object.vtable->klass->name, "InvalidCastException")) {
+                       char *from_name = mono_type_get_full_name (jit_tls->class_cast_from);
+                       char *to_name = mono_type_get_full_name (jit_tls->class_cast_to);
+                       char *msg = g_strdup_printf ("Unable to cast object of type '%s' to type '%s'.", from_name, to_name);
+                       mono_ex->message = mono_string_new (domain, msg);
+                       g_free (from_name);
+                       g_free (to_name);
+                       g_free (msg);
+               }
+               if (!strcmp (mono_ex->object.vtable->klass->name, "ArrayTypeMismatchException")) {
+                       char *from_name = mono_type_get_full_name (jit_tls->class_cast_from);
+                       char *to_name = mono_type_get_full_name (jit_tls->class_cast_to);
+                       char *msg = g_strdup_printf ("Source array of type '%s' cannot be cast to destination array type '%s'.", from_name, to_name);
+                       mono_ex->message = mono_string_new (domain, msg);
+                       g_free (from_name);
+                       g_free (to_name);
+                       g_free (msg);
+               }
        }
 
        if (!call_filter)