MonoInst *target_label; \
target_label = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst)); \
target_label->opcode = OP_LABEL; \
- MONO_INST_LIST_ADD (&target_label->node, \
- &(targetbb)->ins_list); \
+ target_label->next = (targetbb)->code; \
+ (targetbb)->code = target_label; \
target_label->inst_c0 = (targetbb)->native_offset; \
MONO_INST_NEW ((cfg), inst, op); \
inst->inst_i0 = target_label; \
stmt: OP_NOP "0" {
}
+stmp: OP_HARD_NOP "0" {
+ mono_bblock_add_inst (s->cbb, tree);
+}
+
stmt: OP_BREAK "0" {
mono_bblock_add_inst (s->cbb, tree);
}
MonoInst *end_label, *fail_label, *no_proxy_label, *ok_result_label;
int obj_reg = state->left->reg1;
int tmp_reg = mono_regstate_next_int (s->rs);
+ int tmp2_reg = mono_regstate_next_int (s->rs);
int klass_reg = mono_regstate_next_int (s->rs);
MONO_NEW_LABEL (s, end_label);
MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, klass_reg, mono_defaults.transparent_proxy_class, "InvalidCastException");
}
-
- MONO_EMIT_NEW_LOAD_MEMBASE (s, tmp_reg, obj_reg, G_STRUCT_OFFSET (MonoTransparentProxy, remote_class));
- MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, tmp_reg, G_STRUCT_OFFSET (MonoRemoteClass, proxy_class));
-
- MONO_EMIT_NEW_LOAD_MEMBASE (s, tmp_reg, obj_reg, G_STRUCT_OFFSET (MonoTransparentProxy, custom_type_info));
- MONO_EMIT_NEW_COMPARE_IMM_EXC (s, EQ, tmp_reg, 0, "InvalidCastException");
+ MONO_EMIT_NEW_LOAD_MEMBASE (s, tmp2_reg, obj_reg, G_STRUCT_OFFSET (MonoTransparentProxy, custom_type_info));
+ MONO_EMIT_NEW_COMPARE_IMM_EXC (s, EQ, tmp2_reg, 0, "InvalidCastException");
MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
MONO_EMIT_NEW_BRANCH_LABEL (s, OP_BR, end_label);
MONO_EMIT_NEW_LOAD_MEMBASE (s, tmp_reg, obj_reg, G_STRUCT_OFFSET (MonoTransparentProxy, remote_class));
MONO_EMIT_NEW_LOAD_MEMBASE (s, klass_reg, tmp_reg, G_STRUCT_OFFSET (MonoRemoteClass, proxy_class));
- MONO_EMIT_NEW_LOAD_MEMBASE (s, tmp_reg, obj_reg, G_STRUCT_OFFSET (MonoTransparentProxy, custom_type_info));
- MONO_EMIT_NEW_COMPARE_IMM_BRANCH_LABEL (s, CEE_BEQ, tmp_reg, 0, no_proxy_label);
+ MONO_EMIT_NEW_LOAD_MEMBASE (s, tmp2_reg, obj_reg, G_STRUCT_OFFSET (MonoTransparentProxy, custom_type_info));
+ MONO_EMIT_NEW_COMPARE_IMM_BRANCH_LABEL (s, CEE_BEQ, tmp2_reg, 0, no_proxy_label);
mini_emit_isinst (s, klass_reg, klass, fail_label, ok_result_label);
mono_bblock_add_inst (s->cbb, fail_label);
/* Emit code which loads interface_offsets [klass->interface_id]
* The array is stored in memory before vtable.
*/
-#ifndef MONO_ARCH_HAVE_IMT
static void
mini_emit_load_intf_reg_vtable (MonoCompile *s, int intf_reg, int vtable_reg, MonoClass *klass)
{
MONO_EMIT_NEW_LOAD_MEMBASE (s, intf_reg, vtable_reg, -((klass->interface_id + 1) * SIZEOF_VOID_P));
}
}
-#endif
/*
* Emit code which loads into "intf_bit_reg" a nonzero value if the MonoClass
mono_call_inst_add_outarg_reg (cfg, call, method_reg, MONO_ARCH_IMT_REG, FALSE);
#else
- mono_arch_emit_imt_argument (cfg, call);
+ mono_arch_emit_imt_argument (cfg, call, NULL);
#endif
}
#endif
MonoMethod *gmethod = mono_method_get_declaring_generic_method (method);
mono_class_setup_vtable (gmethod->klass);
- slot = gmethod->slot;
+ slot = mono_method_get_vtable_index (gmethod);
g_assert (slot != -1);
} else {
/* Initialize method->slot */
mono_class_setup_vtable (method->klass);
- slot = method->slot;
+ slot = mono_method_get_vtable_index (method);
}
vtable_reg = mono_regstate_next_int (cfg->rs);
MONO_EMIT_NEW_LOAD_MEMBASE (cfg, vtable_reg, this_reg, G_STRUCT_OFFSET (MonoObject, vtable));
if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+ slot_reg = -1;
#ifdef MONO_ARCH_HAVE_IMT
- guint32 imt_slot = mono_method_get_imt_slot (method);
- emit_imt_argument (cfg, (MonoCallInst*)tree, have_imt_arg, imt_reg);
- slot_reg = vtable_reg;
- tree->inst_offset = ((gint32)imt_slot - MONO_IMT_SIZE) * SIZEOF_VOID_P;
-#else
- g_assert (!have_imt_arg);
- slot_reg = mono_regstate_next_int (cfg->rs);
- mini_emit_load_intf_reg_vtable (cfg, slot_reg, vtable_reg, method->klass);
- tree->inst_offset = slot * SIZEOF_VOID_P;
+ if (mono_use_imt) {
+ guint32 imt_slot = mono_method_get_imt_slot (method);
+ emit_imt_argument (cfg, (MonoCallInst*)tree, have_imt_arg, imt_reg);
+ slot_reg = vtable_reg;
+ tree->inst_offset = ((gint32)imt_slot - MONO_IMT_SIZE) * SIZEOF_VOID_P;
+ }
#endif
+ if (slot_reg == -1) {
+ g_assert (!have_imt_arg);
+ slot_reg = mono_regstate_next_int (cfg->rs);
+ mini_emit_load_intf_reg_vtable (cfg, slot_reg, vtable_reg, method->klass);
+ tree->inst_offset = slot * SIZEOF_VOID_P;
+ }
} else {
slot_reg = vtable_reg;
tree->inst_offset = G_STRUCT_OFFSET (MonoVTable, vtable) + (slot * SIZEOF_VOID_P);
} else if (klass->cast_class->flags & TYPE_ATTRIBUTE_INTERFACE) {
mini_emit_castclass_iface_class (s, eclass_reg, klass->cast_class);
} else {
- mini_emit_castclass (s, obj_reg, eclass_reg, klass->cast_class, object_is_null);
+ // Pass -1 as obj_reg to skip the check below for arrays of arrays
+ mini_emit_castclass (s, -1, eclass_reg, klass->cast_class, object_is_null);
}
- if ((klass->rank == 1) && (klass->byval_arg.type == MONO_TYPE_SZARRAY)) {
+ if ((klass->rank == 1) && (klass->byval_arg.type == MONO_TYPE_SZARRAY) && (obj_reg != -1)) {
/* Check that the object is a vector too */
int bounds_reg = mono_regstate_next_int (s->rs);
MONO_EMIT_NEW_LOAD_MEMBASE (s, bounds_reg, obj_reg, G_STRUCT_OFFSET (MonoArray, bounds));