-#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 MonoInst*
-emit_isinst_with_cache (MonoCompile *cfg, MonoClass *klass, MonoInst **args)
-{
- MonoMethod *mono_isinst = mono_marshal_get_isinst_with_cache ();
- return mono_emit_method_call (cfg, mono_isinst, args, NULL);
-}
-
-static MonoInst*
-emit_castclass_with_cache (MonoCompile *cfg, MonoClass *klass, MonoInst **args)
-{
- MonoMethod *mono_castclass = mono_marshal_get_castclass_with_cache ();
- MonoInst *res;
-
- save_cast_details (cfg, klass, args [0]->dreg, TRUE);
- res = mono_emit_method_call (cfg, mono_castclass, args, NULL);
- reset_cast_details (cfg);
-
- return res;
-}
-
-static int
-get_castclass_cache_idx (MonoCompile *cfg)
-{
- /* 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 MonoInst*
-emit_isinst_with_cache_nonshared (MonoCompile *cfg, MonoInst *obj, MonoClass *klass)
-{
- MonoInst *args [3];
- int idx;
-
- args [0] = obj; /* obj */
- EMIT_NEW_CLASSCONST (cfg, args [1], klass); /* klass */
-
- idx = get_castclass_cache_idx (cfg); /* inline cache*/
- args [2] = emit_runtime_constant (cfg, MONO_PATCH_INFO_CASTCLASS_CACHE, GINT_TO_POINTER (idx));
-
- return emit_isinst_with_cache (cfg, klass, args);
-}
-
-static MonoInst*
-emit_castclass_with_cache_nonshared (MonoCompile *cfg, MonoInst *obj, MonoClass *klass)
-{
- MonoInst *args [3];
- int idx;
-
- /* obj */
- args [0] = obj;
-
- /* klass */
- EMIT_NEW_CLASSCONST (cfg, args [1], klass);
-
- /* inline cache*/
- idx = get_castclass_cache_idx (cfg);
- args [2] = emit_runtime_constant (cfg, MONO_PATCH_INFO_CASTCLASS_CACHE, GINT_TO_POINTER (idx));
-
- /*The wrapper doesn't inline well so the bloat of inlining doesn't pay off.*/
- return emit_castclass_with_cache (cfg, klass, args);
-}
-
-/*
- * Returns NULL and set the cfg exception on error.
- */
-static MonoInst*
-handle_castclass (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context_used)
-{
- 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 (mini_class_has_reference_variant_generic_argument (cfg, klass, context_used) || is_complex_isinst (klass)) {
- MonoInst *cache_ins;
-
- cache_ins = 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);
- }
-
- klass_inst = emit_get_rgctx_klass (cfg, context_used, klass, MONO_RGCTX_INFO_KLASS);
- }
-
- NEW_BBLOCK (cfg, is_null_bb);
-
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, obj_reg, 0);
- MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBEQ, is_null_bb);
-
- save_cast_details (cfg, klass, obj_reg, FALSE);
-
- if (mono_class_is_interface (klass)) {
- MONO_EMIT_NEW_LOAD_MEMBASE (cfg, vtable_reg, obj_reg, MONO_STRUCT_OFFSET (MonoObject, vtable));
- mini_emit_iface_cast (cfg, vtable_reg, klass, NULL, NULL);
- } else {
- int klass_reg = alloc_preg (cfg);
-
- MONO_EMIT_NEW_LOAD_MEMBASE (cfg, vtable_reg, obj_reg, MONO_STRUCT_OFFSET (MonoObject, vtable));
-
- if (!klass->rank && !cfg->compile_aot && !(cfg->opt & MONO_OPT_SHARED) && mono_class_is_sealed (klass)) {
- /* the remoting code is broken, access the class for now */
- if (0) { /*FIXME what exactly is broken? This change refers to r39380 from 2005 and mention some remoting fixes were due.*/
- MonoVTable *vt = mono_class_vtable (cfg->domain, klass);
- if (!vt) {
- mono_cfg_set_exception (cfg, MONO_EXCEPTION_TYPE_LOAD);
- cfg->exception_ptr = klass;
- return NULL;
- }
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, vtable_reg, vt);
- } else {
- MONO_EMIT_NEW_LOAD_MEMBASE (cfg, klass_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, klass));
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, klass_reg, klass);
- }
- MONO_EMIT_NEW_COND_EXC (cfg, NE_UN, "InvalidCastException");
- } else {
- MONO_EMIT_NEW_LOAD_MEMBASE (cfg, klass_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, klass));
- mini_emit_castclass_inst (cfg, obj_reg, klass_reg, klass, klass_inst, is_null_bb);
- }
- }
-
- MONO_START_BB (cfg, is_null_bb);
-
- reset_cast_details (cfg);
-
- return src;
-}
-
-/*
- * Returns NULL and set the cfg exception on error.
- */
-static MonoInst*
-handle_isinst (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context_used)
-{
- MonoInst *ins;
- MonoBasicBlock *is_null_bb, *false_bb, *end_bb;
- int obj_reg = src->dreg;
- int vtable_reg = alloc_preg (cfg);
- int res_reg = alloc_ireg_ref (cfg);
- MonoInst *klass_inst = NULL;
-
- if (context_used) {
- MonoInst *args [3];
-
- if(mini_class_has_reference_variant_generic_argument (cfg, klass, context_used) || is_complex_isinst (klass)) {
- MonoInst *cache_ins = 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);
- }
-
- klass_inst = emit_get_rgctx_klass (cfg, context_used, klass, MONO_RGCTX_INFO_KLASS);
- }
-
- NEW_BBLOCK (cfg, is_null_bb);
- NEW_BBLOCK (cfg, false_bb);
- NEW_BBLOCK (cfg, end_bb);
-
- /* Do the assignment at the beginning, so the other assignment can be if converted */
- EMIT_NEW_UNALU (cfg, ins, OP_MOVE, res_reg, obj_reg);
- ins->type = STACK_OBJ;
- ins->klass = klass;
-
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, obj_reg, 0);
- MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBEQ, is_null_bb);
-
- 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);
- } else {
- int klass_reg = alloc_preg (cfg);
-
- if (klass->rank) {
- int rank_reg = alloc_preg (cfg);
- int eclass_reg = alloc_preg (cfg);
-
- 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);
- MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBNE_UN, false_bb);
- MONO_EMIT_NEW_LOAD_MEMBASE (cfg, klass_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, klass));
- MONO_EMIT_NEW_LOAD_MEMBASE (cfg, eclass_reg, klass_reg, MONO_STRUCT_OFFSET (MonoClass, cast_class));
- if (klass->cast_class == mono_defaults.object_class) {
- int parent_reg = alloc_preg (cfg);
- MONO_EMIT_NEW_LOAD_MEMBASE (cfg, parent_reg, eclass_reg, MONO_STRUCT_OFFSET (MonoClass, parent));
- mini_emit_class_check_branch (cfg, parent_reg, mono_defaults.enum_class->parent, OP_PBNE_UN, is_null_bb);
- mini_emit_class_check_branch (cfg, eclass_reg, mono_defaults.enum_class, OP_PBEQ, is_null_bb);
- MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, false_bb);
- } else if (klass->cast_class == mono_defaults.enum_class->parent) {
- mini_emit_class_check_branch (cfg, eclass_reg, mono_defaults.enum_class->parent, OP_PBEQ, is_null_bb);
- mini_emit_class_check_branch (cfg, eclass_reg, mono_defaults.enum_class, OP_PBEQ, is_null_bb);
- MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, false_bb);
- } else if (klass->cast_class == mono_defaults.enum_class) {
- mini_emit_class_check_branch (cfg, eclass_reg, mono_defaults.enum_class, OP_PBEQ, is_null_bb);
- MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, false_bb);
- } 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);
- }
- } else if (mono_class_is_nullable (klass)) {
- g_assert (!context_used);
- MONO_EMIT_NEW_LOAD_MEMBASE (cfg, klass_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, klass));
- /* the is_null_bb target simply copies the input register to the output */
- mini_emit_isninst_cast (cfg, klass_reg, klass->cast_class, false_bb, is_null_bb);
- } else {
- if (!cfg->compile_aot && !(cfg->opt & MONO_OPT_SHARED) && mono_class_is_sealed (klass)) {
- g_assert (!context_used);
- /* the remoting code is broken, access the class for now */
- if (0) {/*FIXME what exactly is broken? This change refers to r39380 from 2005 and mention some remoting fixes were due.*/
- MonoVTable *vt = mono_class_vtable (cfg->domain, klass);
- if (!vt) {
- mono_cfg_set_exception (cfg, MONO_EXCEPTION_TYPE_LOAD);
- cfg->exception_ptr = klass;
- return NULL;
- }
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, vtable_reg, vt);
- } else {
- MONO_EMIT_NEW_LOAD_MEMBASE (cfg, klass_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, klass));
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, klass_reg, klass);
- }
- MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBNE_UN, false_bb);
- MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, is_null_bb);
- } else {
- MONO_EMIT_NEW_LOAD_MEMBASE (cfg, klass_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, klass));
- /* the is_null_bb target simply copies the input register to the output */
- mini_emit_isninst_cast_inst (cfg, klass_reg, klass, klass_inst, false_bb, is_null_bb);
- }
- }
- }
-
- MONO_START_BB (cfg, false_bb);
-
- MONO_EMIT_NEW_PCONST (cfg, res_reg, 0);
- MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, end_bb);
-
- MONO_START_BB (cfg, is_null_bb);
-
- MONO_START_BB (cfg, end_bb);
-
- return ins;
-}
-
-static MonoInst*
-handle_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;
-}
-
-static MonoInst*
-handle_ccastclass (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 a proxy whose type cannot be determined
- an InvalidCastException exception is thrown otherwhise*/
-
- MonoInst *ins;
-#ifndef DISABLE_REMOTING
- MonoBasicBlock *end_bb, *ok_result_bb, *no_proxy_bb, *interface_fail_bb, *fail_1_bb;
-#else
- MonoBasicBlock *ok_result_bb;
-#endif
- int obj_reg = src->dreg;
- int dreg = alloc_ireg (cfg);
- int tmp_reg = alloc_preg (cfg);
-
-#ifndef DISABLE_REMOTING
- int klass_reg = alloc_preg (cfg);
- NEW_BBLOCK (cfg, end_bb);
-#endif
-
- NEW_BBLOCK (cfg, ok_result_bb);
-
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, obj_reg, 0);
- MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBEQ, ok_result_bb);
-
- save_cast_details (cfg, klass, obj_reg, FALSE);
-
- if (mono_class_is_interface (klass)) {
-#ifndef DISABLE_REMOTING
- NEW_BBLOCK (cfg, interface_fail_bb);
-
- MONO_EMIT_NEW_LOAD_MEMBASE (cfg, tmp_reg, obj_reg, MONO_STRUCT_OFFSET (MonoObject, vtable));
- mini_emit_iface_cast (cfg, tmp_reg, klass, interface_fail_bb, ok_result_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 (cfg, klass_reg, mono_defaults.transparent_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_COND_EXC (cfg, EQ, "InvalidCastException");
-
- MONO_EMIT_NEW_ICONST (cfg, dreg, 1);
- MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, end_bb);
-#else
- 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, ok_result_bb);
-#endif
- } else {
-#ifndef DISABLE_REMOTING
- NEW_BBLOCK (cfg, no_proxy_bb);
-
- 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);
-
- NEW_BBLOCK (cfg, fail_1_bb);
-
- mini_emit_isninst_cast (cfg, klass_reg, klass, fail_1_bb, ok_result_bb);
-
- MONO_START_BB (cfg, fail_1_bb);
-
- MONO_EMIT_NEW_ICONST (cfg, dreg, 1);
- MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_BR, end_bb);
-
- MONO_START_BB (cfg, no_proxy_bb);
-
- mini_emit_castclass (cfg, obj_reg, klass_reg, klass, ok_result_bb);
-#else
- g_error ("Transparent proxy support is disabled while trying to JIT code that uses it");
-#endif
- }
-
- MONO_START_BB (cfg, ok_result_bb);
-
- MONO_EMIT_NEW_ICONST (cfg, dreg, 0);
-
-#ifndef DISABLE_REMOTING
- MONO_START_BB (cfg, end_bb);
-#endif
-
- /* FIXME: */
- MONO_INST_NEW (cfg, ins, OP_ICONST);
- ins->dreg = dreg;
- ins->type = STACK_I4;
-
- return ins;
-}
-