Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / mini / type-checking.c
index d190436ea63e93e428c50fd6412de00fd33aee96..e2335af05fb1ba89ed1bda8a322eae1b335ced58 100644 (file)
@@ -1,48 +1,84 @@
+/**
+ * \file
+ */
+
 #include <config.h>
 #include <mono/utils/mono-compiler.h>
 
 #ifndef DISABLE_JIT
 
-#include <mini.h>
-#include <ir-emit.h>
+#include "mini.h"
+#include "ir-emit.h"
 #include <mono/metadata/abi-details.h>
 
 
-//XXX maybe move to mini.h / mini.c?
+#define is_complex_isinst(klass) (mono_class_is_interface (klass) || klass->rank || mono_class_is_nullable (klass) || mono_class_is_marshalbyref (klass) || mono_class_is_sealed (klass) || klass->byval_arg.type == MONO_TYPE_VAR || klass->byval_arg.type == MONO_TYPE_MVAR)
 
 static int
-mini_class_check_context_used (MonoCompile *cfg, MonoClass *klass)
+get_castclass_cache_idx (MonoCompile *cfg)
 {
-       if (cfg->gshared)
-               return mono_class_check_context_used (klass);
-       else
-               return 0;
+       /* Each CASTCLASS_CACHE patch needs a unique index which identifies the call site */
+       cfg->castclass_cache_index ++;
+       return (cfg->method_index << 16) | cfg->castclass_cache_index;
 }
 
+static void
+emit_cached_check_args (MonoCompile *cfg, MonoInst *obj, MonoClass *klass, int context_used, MonoInst *args[3])
+{
+       args [0] = obj;
 
-#define is_complex_isinst(klass) (mono_class_is_interface (klass) || klass->rank || mono_class_is_nullable (klass) || mono_class_is_marshalbyref (klass) || mono_class_is_sealed (klass) || klass->byval_arg.type == MONO_TYPE_VAR || klass->byval_arg.type == MONO_TYPE_MVAR)
+       if (context_used) {
+               MonoInst *cache_ins;
+
+               cache_ins = mini_emit_get_rgctx_klass (cfg, context_used, klass, MONO_RGCTX_INFO_CAST_CACHE);
+
+               /* klass - it's the second element of the cache entry*/
+               EMIT_NEW_LOAD_MEMBASE (cfg, args [1], OP_LOAD_MEMBASE, alloc_preg (cfg), cache_ins->dreg, sizeof (gpointer));
+
+               args [2] = cache_ins; /* cache */
+       } else {
+               int idx;
+
+               EMIT_NEW_CLASSCONST (cfg, args [1], klass); /* klass */
+
+               idx = get_castclass_cache_idx (cfg); /* inline cache*/
+               args [2] = mini_emit_runtime_constant (cfg, MONO_PATCH_INFO_CASTCLASS_CACHE, GINT_TO_POINTER (idx));
+       }
+}
 
 static MonoInst*
-emit_isinst_with_cache (MonoCompile *cfg, MonoClass *klass, MonoInst **args)
+emit_isinst_with_cache (MonoCompile *cfg, MonoInst *obj, MonoClass *klass, int context_used)
 {
+       MonoInst *args [3];
        MonoMethod *mono_isinst = mono_marshal_get_isinst_with_cache ();
+
+       emit_cached_check_args (cfg, obj, klass, context_used, args);
        return mono_emit_method_call (cfg, mono_isinst, args, NULL);
 }
 
-static int
-get_castclass_cache_idx (MonoCompile *cfg)
+static MonoInst*
+emit_castclass_with_cache_no_details (MonoCompile *cfg, MonoInst *obj, MonoClass *klass, int context_used)
 {
-       /* Each CASTCLASS_CACHE patch needs a unique index which identifies the call site */
-       cfg->castclass_cache_index ++;
-       return (cfg->method_index << 16) | cfg->castclass_cache_index;
+       MonoInst *args [3];
+       MonoMethod *mono_castclass = mono_marshal_get_castclass_with_cache ();
+       MonoInst *res;
+
+       emit_cached_check_args (cfg, obj, klass, context_used, args);
+
+       res = mono_emit_method_call (cfg, mono_castclass, args, NULL);
+
+       return res;
 }
 
 static MonoInst*
-emit_castclass_with_cache (MonoCompile *cfg, MonoClass *klass, MonoInst **args)
+emit_castclass_with_cache (MonoCompile *cfg, MonoInst *obj, MonoClass *klass, int context_used)
 {
+       MonoInst *args [3];
        MonoMethod *mono_castclass = mono_marshal_get_castclass_with_cache ();
        MonoInst *res;
 
+       emit_cached_check_args (cfg, obj, klass, context_used, args);
+
        mini_save_cast_details (cfg, klass, args [0]->dreg, TRUE);
        res = mono_emit_method_call (cfg, mono_castclass, args, NULL);
        mini_reset_cast_details (cfg);
@@ -311,6 +347,28 @@ mini_emit_castclass (MonoCompile *cfg, int obj_reg, int klass_reg, MonoClass *kl
        mini_emit_castclass_inst (cfg, obj_reg, klass_reg, klass, NULL, object_is_null);
 }
 
+static void
+emit_special_array_iface_check (MonoCompile *cfg, MonoInst *src, MonoClass* klass, int vtable_reg, MonoBasicBlock *true_bb, int context_used)
+{
+       MonoBasicBlock *not_an_array;
+       int rank_reg;
+
+       if (!klass->is_array_special_interface)
+               return;
+
+       rank_reg = alloc_ireg (cfg);
+
+       NEW_BBLOCK (cfg, not_an_array);
+       MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU1_MEMBASE, rank_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, rank));
+       MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, rank_reg, 1);
+       MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBNE_UN, not_an_array);
+
+       emit_castclass_with_cache_no_details (cfg, src, klass, context_used);
+       MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, true_bb);
+
+       MONO_START_BB (cfg, not_an_array);
+
+}
 
 /*
  * Returns NULL and set the cfg exception on error.
@@ -320,31 +378,15 @@ handle_castclass (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context
 {
        MonoBasicBlock *is_null_bb;
        int obj_reg = src->dreg;
-       int vtable_reg = alloc_preg (cfg);
        MonoInst *klass_inst = NULL;
 
        if (MONO_INS_IS_PCONST_NULL (src))
                return src;
 
        if (context_used) {
-               MonoInst *args [3];
-
-               if (is_complex_isinst (klass)) {
-                       MonoInst *cache_ins;
-
-                       cache_ins = mini_emit_get_rgctx_klass (cfg, context_used, klass, MONO_RGCTX_INFO_CAST_CACHE);
-
-                       /* obj */
-                       args [0] = src;
 
-                       /* klass - it's the second element of the cache entry*/
-                       EMIT_NEW_LOAD_MEMBASE (cfg, args [1], OP_LOAD_MEMBASE, alloc_preg (cfg), cache_ins->dreg, sizeof (gpointer));
-
-                       /* cache */
-                       args [2] = cache_ins;
-
-                       return emit_castclass_with_cache (cfg, klass, args);
-               }
+               if (is_complex_isinst (klass))
+                       return emit_castclass_with_cache (cfg, src, klass, context_used);
 
                klass_inst = mini_emit_get_rgctx_klass (cfg, context_used, klass, MONO_RGCTX_INFO_KLASS);
        }
@@ -369,6 +411,10 @@ handle_castclass (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context
 
                // iface bitmap check failed
                MONO_START_BB (cfg, interface_fail_bb);
+
+               //Check if it's a rank zero array and emit fallback casting
+               emit_special_array_iface_check (cfg, src, klass, tmp_reg, is_null_bb, context_used);
+
                MONO_EMIT_NEW_LOAD_MEMBASE (cfg, klass_reg, tmp_reg, MONO_STRUCT_OFFSET (MonoVTable, klass));
 
                mini_emit_class_check (cfg, klass_reg, mono_defaults.transparent_proxy_class);
@@ -385,9 +431,22 @@ handle_castclass (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context
 
                MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, is_null_bb);
 #else
+               MonoBasicBlock *interface_fail_bb = NULL;
+
                MONO_EMIT_NEW_LOAD_MEMBASE (cfg, tmp_reg, obj_reg, MONO_STRUCT_OFFSET (MonoObject, vtable));
-               mini_emit_iface_cast (cfg, tmp_reg, klass, NULL, NULL);
-               MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, is_null_bb);
+
+               if (klass->is_array_special_interface) {
+                       NEW_BBLOCK (cfg, interface_fail_bb);
+                       mini_emit_iface_cast (cfg, tmp_reg, klass, interface_fail_bb, is_null_bb);
+                       // iface bitmap check failed
+                       MONO_START_BB (cfg, interface_fail_bb);
+
+                       //Check if it's a rank zero array and emit fallback casting
+                       emit_special_array_iface_check (cfg, src, klass, tmp_reg, is_null_bb, context_used);
+               } else {
+                       mini_emit_iface_cast (cfg, tmp_reg, klass, NULL, NULL);
+                       MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, is_null_bb);
+               }
 #endif
        } else if (mono_class_is_marshalbyref (klass)) {
 #ifndef DISABLE_REMOTING
@@ -430,6 +489,7 @@ handle_castclass (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context
                g_error ("Transparent proxy support is disabled while trying to JIT code that uses it");
 #endif
        } else {
+               int vtable_reg = alloc_preg (cfg);
                int klass_reg = alloc_preg (cfg);
 
                MONO_EMIT_NEW_LOAD_MEMBASE (cfg, vtable_reg, obj_reg, MONO_STRUCT_OFFSET (MonoObject, vtable));
@@ -476,19 +536,8 @@ handle_isinst (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context_us
        MonoInst *klass_inst = NULL;
 
        if (context_used) {
-               MonoInst *args [3];
-
-               if(is_complex_isinst (klass)) {
-                       MonoInst *cache_ins = mini_emit_get_rgctx_klass (cfg, context_used, klass, MONO_RGCTX_INFO_CAST_CACHE);
-
-                       args [0] = src; /* obj */
-
-                       /* klass - it's the second element of the cache entry*/
-                       EMIT_NEW_LOAD_MEMBASE (cfg, args [1], OP_LOAD_MEMBASE, alloc_preg (cfg), cache_ins->dreg, sizeof (gpointer));
-
-                       args [2] = cache_ins; /* cache */
-                       return emit_isinst_with_cache (cfg, klass, args);
-               }
+               if(is_complex_isinst (klass))
+                       return emit_isinst_with_cache (cfg, src, klass, context_used);
 
                klass_inst = mini_emit_get_rgctx_klass (cfg, context_used, klass, MONO_RGCTX_INFO_KLASS);
        }
@@ -508,9 +557,95 @@ handle_isinst (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context_us
        MONO_EMIT_NEW_LOAD_MEMBASE (cfg, vtable_reg, obj_reg, MONO_STRUCT_OFFSET (MonoObject, vtable));
 
        if (mono_class_is_interface (klass)) {
-               g_assert (!context_used);
-               /* the is_null_bb target simply copies the input register to the output */
-               mini_emit_iface_cast (cfg, vtable_reg, klass, false_bb, is_null_bb);
+               MonoBasicBlock *interface_fail_bb;
+
+               NEW_BBLOCK (cfg, interface_fail_bb);
+
+               mini_emit_iface_cast (cfg, vtable_reg, klass, interface_fail_bb, is_null_bb);
+               MONO_START_BB (cfg, interface_fail_bb);
+
+               if (klass->is_array_special_interface) {
+                       MonoBasicBlock *not_an_array;
+                       MonoInst *move;
+                       int rank_reg = alloc_ireg (cfg);
+
+                       NEW_BBLOCK (cfg, not_an_array);
+                       MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU1_MEMBASE, rank_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, rank));
+                       MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, rank_reg, 1);
+                       MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBNE_UN, not_an_array);
+
+                       MonoInst *res_inst = emit_isinst_with_cache (cfg, src, klass, context_used);
+                       EMIT_NEW_UNALU (cfg, move, OP_MOVE, res_reg, res_inst->dreg);
+                       MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, end_bb);
+
+                       MONO_START_BB (cfg, not_an_array);
+               }
+
+#ifndef DISABLE_REMOTING
+               int tmp_reg, klass_reg;
+               MonoBasicBlock *call_proxy_isinst;
+
+               NEW_BBLOCK (cfg, call_proxy_isinst);
+
+               klass_reg = alloc_preg (cfg);
+               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, klass_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, klass));
+
+               mini_emit_class_check_branch (cfg, klass_reg, mono_defaults.transparent_proxy_class, OP_PBNE_UN, false_bb);
+
+               tmp_reg = alloc_preg (cfg);
+               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, tmp_reg, obj_reg, MONO_STRUCT_OFFSET (MonoTransparentProxy, custom_type_info));
+               MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, tmp_reg, 0);
+               MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBEQ, false_bb);
+
+               MONO_START_BB (cfg, call_proxy_isinst);
+
+               MonoInst *args [1] = { src };
+               MonoInst *proxy_test_inst = mono_emit_method_call (cfg, mono_marshal_get_proxy_cancast (klass), args, NULL);
+               MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, proxy_test_inst->dreg, 0);
+               MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBNE_UN, is_null_bb);
+#else
+               MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, false_bb);
+#endif
+
+       } else if (mono_class_is_marshalbyref (klass)) {
+
+#ifndef DISABLE_REMOTING
+               int tmp_reg, klass_reg;
+               MonoBasicBlock *no_proxy_bb, *call_proxy_isinst;
+
+               NEW_BBLOCK (cfg, no_proxy_bb);
+               NEW_BBLOCK (cfg, call_proxy_isinst);
+
+               klass_reg = alloc_preg (cfg);
+               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, klass_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, klass));
+
+               mini_emit_class_check_branch (cfg, klass_reg, mono_defaults.transparent_proxy_class, OP_PBNE_UN, no_proxy_bb);
+
+               tmp_reg = alloc_preg (cfg);
+               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, tmp_reg, obj_reg, MONO_STRUCT_OFFSET (MonoTransparentProxy, remote_class));
+               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, klass_reg, tmp_reg, MONO_STRUCT_OFFSET (MonoRemoteClass, proxy_class));
+
+               tmp_reg = alloc_preg (cfg);
+               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, tmp_reg, obj_reg, MONO_STRUCT_OFFSET (MonoTransparentProxy, custom_type_info));
+               MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, tmp_reg, 0);
+               MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBEQ, false_bb);
+
+               mini_emit_isninst_cast (cfg, klass_reg, klass, call_proxy_isinst, is_null_bb);
+
+               MONO_START_BB (cfg, call_proxy_isinst);
+
+               MonoInst *args [1] = { src };
+               MonoInst *proxy_test_inst = mono_emit_method_call (cfg, mono_marshal_get_proxy_cancast (klass), args, NULL);
+               MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, proxy_test_inst->dreg, 0);
+               MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBNE_UN, is_null_bb);
+               MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, false_bb);
+
+               MONO_START_BB (cfg, no_proxy_bb);
+
+               mini_emit_isninst_cast (cfg, klass_reg, klass, false_bb, is_null_bb);
+#else
+               g_error ("transparent proxy support is disabled while trying to JIT code that uses it");
+#endif
        } else {
                int klass_reg = alloc_preg (cfg);
 
@@ -518,6 +653,14 @@ handle_isinst (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context_us
                        int rank_reg = alloc_preg (cfg);
                        int eclass_reg = alloc_preg (cfg);
 
+                       if ((klass->rank == 1) && (klass->byval_arg.type == MONO_TYPE_SZARRAY)) {
+                               /* Check that the object is a vector too */
+                               int bounds_reg = alloc_preg (cfg);
+                               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, bounds_reg, obj_reg, MONO_STRUCT_OFFSET (MonoArray, bounds));
+                               MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, bounds_reg, 0);
+                               MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBNE_UN, false_bb);
+                       }
+
                        g_assert (!context_used);
                        MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU1_MEMBASE, rank_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, rank));
                        MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, rank_reg, klass->rank);
@@ -540,14 +683,6 @@ handle_isinst (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context_us
                        } else if (mono_class_is_interface (klass->cast_class)) {
                                mini_emit_iface_class_cast (cfg, eclass_reg, klass->cast_class, false_bb, is_null_bb);
                        } else {
-                               if ((klass->rank == 1) && (klass->byval_arg.type == MONO_TYPE_SZARRAY)) {
-                                       /* Check that the object is a vector too */
-                                       int bounds_reg = alloc_preg (cfg);
-                                       MONO_EMIT_NEW_LOAD_MEMBASE (cfg, bounds_reg, obj_reg, MONO_STRUCT_OFFSET (MonoArray, bounds));
-                                       MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, bounds_reg, 0);
-                                       MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBNE_UN, false_bb);
-                               }
-
                                /* the is_null_bb target simply copies the input register to the output */
                                mini_emit_isninst_cast (cfg, eclass_reg, klass->cast_class, false_bb, is_null_bb);
                        }
@@ -584,7 +719,7 @@ handle_isinst (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context_us
 
        MONO_START_BB (cfg, false_bb);
 
-       MONO_EMIT_NEW_PCONST (cfg, res_reg, 0);
+       MONO_EMIT_NEW_PCONST (cfg, res_reg, NULL);
        MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, end_bb);
 
        MONO_START_BB (cfg, is_null_bb);
@@ -611,41 +746,12 @@ mono_decompose_typecheck (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins)
        NEW_BBLOCK (cfg, first_bb);
        cfg->cbb = first_bb;
 
-       if (mini_class_has_reference_variant_generic_argument (cfg, klass, context_used) || klass->is_array_special_interface) {
-               MonoInst *args [3];
-               args [0] = source; /* obj */
-
-               if (context_used) {
-                       MonoInst *cache_ins;
-
-                       cache_ins = mini_emit_get_rgctx_klass (cfg, context_used, klass, MONO_RGCTX_INFO_CAST_CACHE);
-
-                       /* klass - it's the second element of the cache entry*/
-                       EMIT_NEW_LOAD_MEMBASE (cfg, args [1], OP_LOAD_MEMBASE, alloc_preg (cfg), cache_ins->dreg, sizeof (gpointer));
-
-                       args [2] = cache_ins; /* cache */
-               } else {
-                       int idx;
-
-                       EMIT_NEW_CLASSCONST (cfg, args [1], klass); /* klass */
-
-                       idx = get_castclass_cache_idx (cfg); /* inline cache*/
-                       args [2] = mini_emit_runtime_constant (cfg, MONO_PATCH_INFO_CASTCLASS_CACHE, GINT_TO_POINTER (idx));
-               }
+       if (mini_class_has_reference_variant_generic_argument (cfg, klass, context_used)) {
                if (is_isinst)
-                       ret = emit_isinst_with_cache (cfg, klass, args);
+                       ret = emit_isinst_with_cache (cfg, source, klass, context_used);
                else
-                       ret = emit_castclass_with_cache (cfg, klass, args);
+                       ret = emit_castclass_with_cache (cfg, source, klass, context_used);
 
-       } else if (!context_used && is_isinst && (mono_class_is_marshalbyref (klass) || mono_class_is_interface (klass))) {
-               MonoInst *iargs [1];
-               int costs;
-
-               iargs [0] = source;
-               MonoMethod *wrapper = mono_marshal_get_isinst (klass);
-               costs = mini_inline_method (cfg, wrapper, mono_method_signature (wrapper), iargs, 0, 0, TRUE);
-               g_assert (costs > 0);
-               ret = iargs [0];
        } else {
                if (is_isinst)
                        ret = handle_isinst (cfg, klass, source, context_used);
@@ -680,119 +786,6 @@ mono_decompose_typechecks (MonoCompile *cfg)
        
 }
 
-//Those two functions will go away as we get rid of CEE_MONO_CISINST and CEE_MONO_CCASTCLASS.
-MonoInst*
-mini_emit_cisinst (MonoCompile *cfg, MonoClass *klass, MonoInst *src)
-{
-       /* This opcode takes as input an object reference and a class, and returns:
-       0) if the object is an instance of the class,
-       1) if the object is not instance of the class,
-       2) if the object is a proxy whose type cannot be determined */
-
-       MonoInst *ins;
-#ifndef DISABLE_REMOTING
-       MonoBasicBlock *true_bb, *false_bb, *false2_bb, *end_bb, *no_proxy_bb, *interface_fail_bb;
-#else
-       MonoBasicBlock *true_bb, *false_bb, *end_bb;
-#endif
-       int obj_reg = src->dreg;
-       int dreg = alloc_ireg (cfg);
-       int tmp_reg;
-#ifndef DISABLE_REMOTING
-       int klass_reg = alloc_preg (cfg);
-#endif
-
-       NEW_BBLOCK (cfg, true_bb);
-       NEW_BBLOCK (cfg, false_bb);
-       NEW_BBLOCK (cfg, end_bb);
-#ifndef DISABLE_REMOTING
-       NEW_BBLOCK (cfg, false2_bb);
-       NEW_BBLOCK (cfg, no_proxy_bb);
-#endif
-
-       MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, obj_reg, 0);
-       MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBEQ, false_bb);
-
-       if (mono_class_is_interface (klass)) {
-#ifndef DISABLE_REMOTING
-               NEW_BBLOCK (cfg, interface_fail_bb);
-#endif
-
-               tmp_reg = alloc_preg (cfg);
-               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, tmp_reg, obj_reg, MONO_STRUCT_OFFSET (MonoObject, vtable));
-#ifndef DISABLE_REMOTING
-               mini_emit_iface_cast (cfg, tmp_reg, klass, interface_fail_bb, true_bb);
-               MONO_START_BB (cfg, interface_fail_bb);
-               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, klass_reg, tmp_reg, MONO_STRUCT_OFFSET (MonoVTable, klass));
-               
-               mini_emit_class_check_branch (cfg, klass_reg, mono_defaults.transparent_proxy_class, OP_PBNE_UN, false_bb);
-
-               tmp_reg = alloc_preg (cfg);
-               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, tmp_reg, obj_reg, MONO_STRUCT_OFFSET (MonoTransparentProxy, custom_type_info));
-               MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, tmp_reg, 0);
-               MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBNE_UN, false2_bb);                
-#else
-               mini_emit_iface_cast (cfg, tmp_reg, klass, false_bb, true_bb);
-#endif
-       } else {
-#ifndef DISABLE_REMOTING
-               tmp_reg = alloc_preg (cfg);
-               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, tmp_reg, obj_reg, MONO_STRUCT_OFFSET (MonoObject, vtable));
-               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, klass_reg, tmp_reg, MONO_STRUCT_OFFSET (MonoVTable, klass));
-
-               mini_emit_class_check_branch (cfg, klass_reg, mono_defaults.transparent_proxy_class, OP_PBNE_UN, no_proxy_bb);          
-               tmp_reg = alloc_preg (cfg);
-               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, tmp_reg, obj_reg, MONO_STRUCT_OFFSET (MonoTransparentProxy, remote_class));
-               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, klass_reg, tmp_reg, MONO_STRUCT_OFFSET (MonoRemoteClass, proxy_class));
-
-               tmp_reg = alloc_preg (cfg);             
-               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, tmp_reg, obj_reg, MONO_STRUCT_OFFSET (MonoTransparentProxy, custom_type_info));
-               MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, tmp_reg, 0);
-               MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBEQ, no_proxy_bb);
-               
-               mini_emit_isninst_cast (cfg, klass_reg, klass, false2_bb, true_bb);
-               MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, false2_bb);
-
-               MONO_START_BB (cfg, no_proxy_bb);
-
-               mini_emit_isninst_cast (cfg, klass_reg, klass, false_bb, true_bb);
-#else
-               g_error ("transparent proxy support is disabled while trying to JIT code that uses it");
-#endif
-       }
-
-       MONO_START_BB (cfg, false_bb);
-
-       MONO_EMIT_NEW_ICONST (cfg, dreg, 1);
-       MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, end_bb);
-
-#ifndef DISABLE_REMOTING
-       MONO_START_BB (cfg, false2_bb);
-
-       MONO_EMIT_NEW_ICONST (cfg, dreg, 2);
-       MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, end_bb);
-#endif
-
-       MONO_START_BB (cfg, true_bb);
-
-       MONO_EMIT_NEW_ICONST (cfg, dreg, 0);
-
-       MONO_START_BB (cfg, end_bb);
-
-       /* FIXME: */
-       MONO_INST_NEW (cfg, ins, OP_ICONST);
-       ins->dreg = dreg;
-       ins->type = STACK_I4;
-
-       return ins;
-}
-
-MonoInst*
-mini_emit_ccastclass (MonoCompile *cfg, MonoClass *klass, MonoInst *src)
-{
-       g_error ("not longer needed!");
-       return NULL;
-}
 
 //API used by method-to-ir.c
 void
@@ -801,4 +794,7 @@ mini_emit_class_check (MonoCompile *cfg, int klass_reg, MonoClass *klass)
        mini_emit_class_check_inst (cfg, klass_reg, klass, NULL);
 }
 
-#endif
\ No newline at end of file
+#else
+
+MONO_EMPTY_SOURCE_FILE (type_checking);
+#endif