{
MonoMethodHeader *header = cfg->header;
MonoExceptionClause *clause;
- MonoBasicBlock *handler;
int i;
GList *res = NULL;
clause = &header->clauses [i];
if (MONO_OFFSET_IN_CLAUSE (clause, (ip - header->code)) &&
(!MONO_OFFSET_IN_CLAUSE (clause, (target - header->code)))) {
- if (clause->flags == type) {
- handler = cfg->cil_offset_to_bb [clause->handler_offset];
- g_assert (handler);
- res = g_list_append (res, handler);
- }
+ if (clause->flags == type)
+ res = g_list_append (res, clause);
}
}
return res;
}
}
-/*
- * Emit code which loads into "intf_bit_reg" a nonzero value if the MonoClass
- * stored in "klass_reg" implements the interface "klass".
- */
static void
-mini_emit_load_intf_bit_reg_class (MonoCompile *cfg, int intf_bit_reg, int klass_reg, MonoClass *klass)
+mini_emit_interface_bitmap_check (MonoCompile *cfg, int intf_bit_reg, int base_reg, int offset, MonoClass *klass)
{
int ibitmap_reg = alloc_preg (cfg);
+#ifdef COMPRESSED_INTERFACE_BITMAP
+ MonoInst *args [2];
+ MonoInst *res, *ins;
+ NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, ibitmap_reg, base_reg, offset);
+ MONO_ADD_INS (cfg->cbb, ins);
+ args [0] = ins;
+ if (cfg->compile_aot)
+ EMIT_NEW_AOTCONST (cfg, args [1], MONO_PATCH_INFO_IID, klass);
+ else
+ EMIT_NEW_ICONST (cfg, args [1], klass->interface_id);
+ res = mono_emit_jit_icall (cfg, mono_class_interface_match, args);
+ MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, intf_bit_reg, res->dreg);
+#else
int ibitmap_byte_reg = alloc_preg (cfg);
- MONO_EMIT_NEW_LOAD_MEMBASE (cfg, ibitmap_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, interface_bitmap));
+ MONO_EMIT_NEW_LOAD_MEMBASE (cfg, ibitmap_reg, base_reg, offset);
if (cfg->compile_aot) {
int iid_reg = alloc_preg (cfg);
MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, ibitmap_byte_reg, ibitmap_reg, klass->interface_id >> 3);
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_AND_IMM, intf_bit_reg, ibitmap_byte_reg, 1 << (klass->interface_id & 7));
}
+#endif
+}
+
+/*
+ * Emit code which loads into "intf_bit_reg" a nonzero value if the MonoClass
+ * stored in "klass_reg" implements the interface "klass".
+ */
+static void
+mini_emit_load_intf_bit_reg_class (MonoCompile *cfg, int intf_bit_reg, int klass_reg, MonoClass *klass)
+{
+ mini_emit_interface_bitmap_check (cfg, intf_bit_reg, klass_reg, G_STRUCT_OFFSET (MonoClass, interface_bitmap), klass);
}
/*
static void
mini_emit_load_intf_bit_reg_vtable (MonoCompile *cfg, int intf_bit_reg, int vtable_reg, MonoClass *klass)
{
- int ibitmap_reg = alloc_preg (cfg);
- int ibitmap_byte_reg = alloc_preg (cfg);
-
- MONO_EMIT_NEW_LOAD_MEMBASE (cfg, ibitmap_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, interface_bitmap));
-
- if (cfg->compile_aot) {
- int iid_reg = alloc_preg (cfg);
- int shifted_iid_reg = alloc_preg (cfg);
- int ibitmap_byte_address_reg = alloc_preg (cfg);
- int masked_iid_reg = alloc_preg (cfg);
- int iid_one_bit_reg = alloc_preg (cfg);
- int iid_bit_reg = alloc_preg (cfg);
- MONO_EMIT_NEW_AOTCONST (cfg, iid_reg, klass, MONO_PATCH_INFO_IID);
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ISHR_IMM, shifted_iid_reg, iid_reg, 3);
- MONO_EMIT_NEW_BIALU (cfg, OP_PADD, ibitmap_byte_address_reg, ibitmap_reg, shifted_iid_reg);
- MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU1_MEMBASE, ibitmap_byte_reg, ibitmap_byte_address_reg, 0);
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_AND_IMM, masked_iid_reg, iid_reg, 7);
- MONO_EMIT_NEW_ICONST (cfg, iid_one_bit_reg, 1);
- MONO_EMIT_NEW_BIALU (cfg, OP_ISHL, iid_bit_reg, iid_one_bit_reg, masked_iid_reg);
- MONO_EMIT_NEW_BIALU (cfg, OP_IAND, intf_bit_reg, ibitmap_byte_reg, iid_bit_reg);
- } else {
- MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, ibitmap_byte_reg, ibitmap_reg, klass->interface_id >> 3);
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_IAND_IMM, intf_bit_reg, ibitmap_byte_reg, 1 << (klass->interface_id & 7));
- }
+ mini_emit_interface_bitmap_check (cfg, intf_bit_reg, vtable_reg, G_STRUCT_OFFSET (MonoVTable, interface_bitmap), klass);
}
/*
}
}
-#endif /* DISABLE_JIT */
-
void
mini_emit_memcpy (MonoCompile *cfg, int destreg, int doffset, int srcreg, int soffset, int size, int align)
{
}
}
-#ifndef DISABLE_JIT
-
static int
ret_type_to_call_opcode (MonoType *type, int calli, int virt, MonoGenericSharingContext *gsctx)
{
* Returns NULL and set the cfg exception on error.
*/
static MonoInst*
-handle_alloc (MonoCompile *cfg, MonoClass *klass, gboolean for_box)
+handle_alloc (MonoCompile *cfg, MonoClass *klass, gboolean for_box, int context_used)
{
MonoInst *iargs [2];
void *alloc_ftn;
+ if (context_used) {
+ MonoInst *data;
+ int rgctx_info;
+ MonoInst *iargs [2];
+
+ /*
+ FIXME: we cannot get managed_alloc here because we can't get
+ the class's vtable (because it's not a closed class)
+
+ MonoVTable *vtable = mono_class_vtable (cfg->domain, klass);
+ MonoMethod *managed_alloc = mono_gc_get_managed_allocator (vtable, for_box);
+ */
+
+ if (cfg->opt & MONO_OPT_SHARED)
+ rgctx_info = MONO_RGCTX_INFO_KLASS;
+ else
+ rgctx_info = MONO_RGCTX_INFO_VTABLE;
+ data = emit_get_rgctx_klass (cfg, context_used, klass, rgctx_info);
+
+ if (cfg->opt & MONO_OPT_SHARED) {
+ EMIT_NEW_DOMAINCONST (cfg, iargs [0]);
+ iargs [1] = data;
+ alloc_ftn = mono_object_new;
+ } else {
+ iargs [0] = data;
+ alloc_ftn = mono_object_new_specific;
+ }
+
+ return mono_emit_jit_icall (cfg, alloc_ftn, iargs);
+ }
+
if (cfg->opt & MONO_OPT_SHARED) {
EMIT_NEW_DOMAINCONST (cfg, iargs [0]);
EMIT_NEW_CLASSCONST (cfg, iargs [1], klass);
return mono_emit_jit_icall (cfg, alloc_ftn, iargs);
}
-
-static MonoInst*
-handle_alloc_from_inst (MonoCompile *cfg, MonoClass *klass, MonoInst *data_inst,
- gboolean for_box)
-{
- MonoInst *iargs [2];
- MonoMethod *managed_alloc = NULL;
- void *alloc_ftn;
-
- /*
- FIXME: we cannot get managed_alloc here because we can't get
- the class's vtable (because it's not a closed class)
-
- MonoVTable *vtable = mono_class_vtable (cfg->domain, klass);
- MonoMethod *managed_alloc = mono_gc_get_managed_allocator (vtable, for_box);
- */
-
- if (cfg->opt & MONO_OPT_SHARED) {
- EMIT_NEW_DOMAINCONST (cfg, iargs [0]);
- iargs [1] = data_inst;
- alloc_ftn = mono_object_new;
- } else {
- if (managed_alloc) {
- iargs [0] = data_inst;
- return mono_emit_method_call (cfg, managed_alloc, iargs, NULL);
- }
-
- iargs [0] = data_inst;
- alloc_ftn = mono_object_new_specific;
- }
-
- return mono_emit_jit_icall (cfg, alloc_ftn, iargs);
-}
/*
* Returns NULL and set the cfg exception on error.
*/
static MonoInst*
-handle_box (MonoCompile *cfg, MonoInst *val, MonoClass *klass)
+handle_box (MonoCompile *cfg, MonoInst *val, MonoClass *klass, int context_used)
{
MonoInst *alloc, *ins;
if (mono_class_is_nullable (klass)) {
MonoMethod* method = mono_class_get_method_from_name (klass, "Box", 1);
- return mono_emit_method_call (cfg, method, &val, NULL);
+
+ if (context_used) {
+ /* FIXME: What if the class is shared? We might not
+ have to get the method address from the RGCTX. */
+ MonoInst *addr = emit_get_rgctx_method (cfg, context_used, method,
+ MONO_RGCTX_INFO_GENERIC_METHOD_CODE);
+ MonoInst *rgctx = emit_get_rgctx (cfg, cfg->current_method, context_used);
+
+ return mono_emit_rgctx_calli (cfg, mono_method_signature (method), &val, addr, rgctx);
+ } else {
+ return mono_emit_method_call (cfg, method, &val, NULL);
+ }
}
- alloc = handle_alloc (cfg, klass, TRUE);
+ alloc = handle_alloc (cfg, klass, TRUE, context_used);
if (!alloc)
return NULL;
return alloc;
}
-static MonoInst *
-handle_box_from_inst (MonoCompile *cfg, MonoInst *val, MonoClass *klass, int context_used, MonoInst *data_inst)
-{
- MonoInst *alloc, *ins;
-
- if (mono_class_is_nullable (klass)) {
- MonoMethod* method = mono_class_get_method_from_name (klass, "Box", 1);
- /* FIXME: What if the class is shared? We might not
- have to get the method address from the RGCTX. */
- MonoInst *addr = emit_get_rgctx_method (cfg, context_used, method,
- MONO_RGCTX_INFO_GENERIC_METHOD_CODE);
- MonoInst *rgctx = emit_get_rgctx (cfg, cfg->current_method, context_used);
-
- return mono_emit_rgctx_calli (cfg, mono_method_signature (method), &val, addr, rgctx);
- } else {
- alloc = handle_alloc_from_inst (cfg, klass, data_inst, TRUE);
-
- EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, &klass->byval_arg, alloc->dreg, sizeof (MonoObject), val->dreg);
-
- return alloc;
- }
-}
-
// FIXME: This doesn't work yet (class libs tests fail?)
#define is_complex_isinst(klass) (TRUE || (klass->flags & TYPE_ATTRIBUTE_INTERFACE) || klass->rank || mono_class_is_nullable (klass) || klass->marshalbyref || (klass->flags & TYPE_ATTRIBUTE_SEALED) || mono_class_has_variant_generic_params (klass) || klass->byval_arg.type == MONO_TYPE_VAR || klass->byval_arg.type == MONO_TYPE_MVAR)
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);
+
if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
NEW_BBLOCK (cfg, interface_fail_bb);
MonoDomain *domain;
guint8 **code_slot;
- obj = handle_alloc (cfg, klass, FALSE);
+ obj = handle_alloc (cfg, klass, FALSE, 0);
if (!obj)
return NULL;
}
static MonoInst*
-mini_emit_ldelema_1_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, MonoInst *index)
+mini_emit_ldelema_1_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, MonoInst *index, gboolean bcheck)
{
MonoInst *ins;
guint32 size;
}
#endif
- MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, index2_reg);
+ if (bcheck)
+ MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, index2_reg);
#if defined(TARGET_X86) || defined(TARGET_AMD64)
if (size == 1 || size == 2 || size == 4 || size == 8) {
rank = mono_method_signature (cmethod)->param_count - (is_set? 1: 0);
if (rank == 1)
- return mini_emit_ldelema_1_ins (cfg, cmethod->klass->element_class, sp [0], sp [1]);
+ return mini_emit_ldelema_1_ins (cfg, cmethod->klass->element_class, sp [0], sp [1], TRUE);
#ifndef MONO_ARCH_EMULATE_MUL_DIV
/* emit_ldelema_2 depends on OP_LMUL */
}
}
+/* optimize the simple GetGenericValueImpl/SetGenericValueImpl generic icalls */
+static MonoInst*
+emit_array_generic_access (MonoCompile *cfg, MonoMethodSignature *fsig, MonoInst **args, int is_set)
+{
+ MonoInst *addr, *store, *load;
+ MonoClass *eklass = mono_class_from_mono_type (fsig->params [2]);
+
+ /* the bounds check is already done by the callers */
+ addr = mini_emit_ldelema_1_ins (cfg, eklass, args [0], args [1], FALSE);
+ if (is_set) {
+ EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, load, &eklass->byval_arg, args [2]->dreg, 0);
+ EMIT_NEW_STORE_MEMBASE_TYPE (cfg, store, &eklass->byval_arg, addr->dreg, 0, load->dreg);
+ } else {
+ EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, load, &eklass->byval_arg, addr->dreg, 0);
+ EMIT_NEW_STORE_MEMBASE_TYPE (cfg, store, &eklass->byval_arg, args [2]->dreg, 0, load->dreg);
+ }
+ return store;
+}
+
static MonoInst*
mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args)
{
} else
return NULL;
} else if (cmethod->klass == mono_defaults.array_class) {
+ if (strcmp (cmethod->name + 1, "etGenericValueImpl") == 0)
+ return emit_array_generic_access (cfg, fsig, args, *cmethod->name == 'S');
if (cmethod->name [0] != 'g')
return NULL;
return (MonoInst*)mono_emit_method_call (cfg, fast_method, args, NULL);
#endif
- } else if (mini_class_is_system_array (cmethod->klass) &&
- strcmp (cmethod->name, "GetGenericValueImpl") == 0) {
- MonoInst *addr, *store, *load;
- MonoClass *eklass = mono_class_from_mono_type (fsig->params [1]);
-
- addr = mini_emit_ldelema_1_ins (cfg, eklass, args [0], args [1]);
- EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, load, &eklass->byval_arg, addr->dreg, 0);
- EMIT_NEW_STORE_MEMBASE_TYPE (cfg, store, &eklass->byval_arg, args [2]->dreg, 0, load->dreg);
- return store;
} else if (cmethod->klass->image == mono_defaults.corlib &&
(strcmp (cmethod->klass->name_space, "System.Threading") == 0) &&
(strcmp (cmethod->klass->name, "Interlocked") == 0)) {
size = 4;
else if (is_ref || fsig->params [1]->type == MONO_TYPE_I)
size = sizeof (gpointer);
- else if (sizeof (gpointer) == 8 && fsig->params [1]->type == MONO_TYPE_I4)
+ else if (sizeof (gpointer) == 8 && fsig->params [1]->type == MONO_TYPE_I8)
size = 8;
if (size == 4) {
MONO_INST_NEW (cfg, ins, OP_ATOMIC_CAS_I4);
ensure_method_is_allowed_to_access_field (MonoCompile *cfg, MonoMethod *caller, MonoClassField *field,
MonoBasicBlock *bblock, unsigned char *ip)
{
- /* there's no restriction to access Transparent or SafeCritical fields, so we only check calls to Critical methods */
- if (mono_security_core_clr_class_level (mono_field_get_parent (field)) != MONO_SECURITY_CORE_CLR_CRITICAL)
- return;
-
/* we can't get the coreclr security level on wrappers since they don't have the attributes */
- caller = get_original_method (caller);
- if (!caller)
- return;
-
- /* caller is Critical! only SafeCritical and Critical callers can access the field, so we throw if caller is Transparent */
- if (mono_security_core_clr_method_level (caller, TRUE) == MONO_SECURITY_CORE_CLR_TRANSPARENT)
- emit_throw_exception (cfg, mono_get_exception_field_access ());
+ MonoException *ex = mono_security_core_clr_is_field_access_allowed (get_original_method (caller), field);
+ if (ex)
+ emit_throw_exception (cfg, ex);
}
static void
ensure_method_is_allowed_to_call_method (MonoCompile *cfg, MonoMethod *caller, MonoMethod *callee,
MonoBasicBlock *bblock, unsigned char *ip)
{
- /* there's no restriction to call Transparent or SafeCritical code, so we only check calls to Critical methods */
- if (mono_security_core_clr_method_level (callee, TRUE) != MONO_SECURITY_CORE_CLR_CRITICAL)
- return;
-
/* we can't get the coreclr security level on wrappers since they don't have the attributes */
- caller = get_original_method (caller);
- if (!caller)
- return;
-
- /* caller is Critical! only SafeCritical and Critical callers can call it, so we throw if the caller is Transparent */
- if (mono_security_core_clr_method_level (caller, TRUE) == MONO_SECURITY_CORE_CLR_TRANSPARENT)
- emit_throw_exception (cfg, mono_get_exception_method_access ());
+ MonoException *ex = mono_security_core_clr_is_call_allowed (get_original_method (caller), callee);
+ if (ex)
+ emit_throw_exception (cfg, ex);
}
/*
/* MS.NET seems to silently convert this to a callvirt */
virtual = 1;
+ {
+ /*
+ * MS.NET accepts non virtual calls to virtual final methods of transparent proxy classes and
+ * converts to a callvirt.
+ *
+ * tests/bug-515884.il is an example of this behavior
+ */
+ const int test_flags = METHOD_ATTRIBUTE_VIRTUAL | METHOD_ATTRIBUTE_FINAL | METHOD_ATTRIBUTE_STATIC;
+ const int expected_flags = METHOD_ATTRIBUTE_VIRTUAL | METHOD_ATTRIBUTE_FINAL;
+ if (!virtual && cmethod->klass->marshalbyref && (cmethod->flags & test_flags) == expected_flags && cfg->method->wrapper_type == MONO_WRAPPER_NONE)
+ virtual = 1;
+ }
+
if (!cmethod->klass->inited)
if (!mono_class_init (cmethod->klass))
goto load_error;
array_rank = cmethod->klass->rank;
fsig = mono_method_signature (cmethod);
} else {
- if (mono_method_signature (cmethod)->pinvoke) {
+ fsig = mono_method_signature (cmethod);
+
+ if (!fsig)
+ goto load_error;
+
+ if (fsig->pinvoke) {
MonoMethod *wrapper = mono_marshal_get_native_wrapper (cmethod,
check_for_pending_exc, FALSE);
fsig = mono_method_signature (wrapper);
*/
EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, ins, &constrained_call->byval_arg, sp [0]->dreg, 0);
ins->klass = constrained_call;
- sp [0] = handle_box (cfg, ins, constrained_call);
+ sp [0] = handle_box (cfg, ins, constrained_call, mono_class_check_context_used (constrained_call));
CHECK_CFG_EXCEPTION;
} else if (!constrained_call->valuetype) {
int dreg = alloc_preg (cfg);
if (!MONO_TYPE_IS_VOID (fsig->ret))
*sp++ = mono_emit_widen_call_res (cfg, ins, fsig);
+ CHECK_CFG_EXCEPTION;
+
ip += 5;
ins_flag = 0;
break;
MONO_ADD_INS (bblock, ins);
link_bblock (cfg, bblock, end_bblock);
start_new_bblock = 1;
+
+ CHECK_CFG_EXCEPTION;
+
/* skip CEE_RET as well */
ip += 6;
ins_flag = 0;
sp++;
}
+ CHECK_CFG_EXCEPTION;
+
ip += 5;
ins_flag = 0;
break;
if (!MONO_TYPE_IS_VOID (fsig->ret))
*sp++ = mono_emit_widen_call_res (cfg, ins, fsig);
+ CHECK_CFG_EXCEPTION;
+
ip += 5;
ins_flag = 0;
break;
g_assert_not_reached ();
}
+ CHECK_CFG_EXCEPTION;
+
ip += 5;
ins_flag = 0;
break;
if (!MONO_TYPE_IS_VOID (fsig->ret))
*sp++ = mono_emit_widen_call_res (cfg, ins, fsig);
+ CHECK_CFG_EXCEPTION;
+
ip += 5;
ins_flag = 0;
break;
if (!MONO_TYPE_IS_VOID (fsig->ret))
*sp++ = mono_emit_widen_call_res (cfg, ins, fsig);
+ CHECK_CFG_EXCEPTION;
+
ip += 5;
ins_flag = 0;
break;
case CEE_CONV_U:
CHECK_STACK (1);
ADD_UNOP (*ip);
+ CHECK_CFG_EXCEPTION;
ip++;
break;
case CEE_ADD_OVF:
* will be transformed into a normal call there.
*/
} else if (context_used) {
- MonoInst *data;
- int rgctx_info;
-
- if (cfg->opt & MONO_OPT_SHARED)
- rgctx_info = MONO_RGCTX_INFO_KLASS;
- else
- rgctx_info = MONO_RGCTX_INFO_VTABLE;
- data = emit_get_rgctx_klass (cfg, context_used, cmethod->klass, rgctx_info);
-
- alloc = handle_alloc_from_inst (cfg, cmethod->klass, data, FALSE);
+ alloc = handle_alloc (cfg, cmethod->klass, FALSE, context_used);
*sp = alloc;
} else {
MonoVTable *vtable = mono_class_vtable (cfg->domain, cmethod->klass);
class_inits = g_slist_prepend (class_inits, vtable);
}
- alloc = handle_alloc (cfg, cmethod->klass, FALSE);
+ alloc = handle_alloc (cfg, cmethod->klass, FALSE, 0);
*sp = alloc;
}
CHECK_CFG_EXCEPTION; /*for handle_alloc*/
break;
}
- if (context_used) {
- MonoInst *data;
- int rgctx_info;
-
- if (cfg->opt & MONO_OPT_SHARED)
- rgctx_info = MONO_RGCTX_INFO_KLASS;
- else
- rgctx_info = MONO_RGCTX_INFO_VTABLE;
- data = emit_get_rgctx_klass (cfg, context_used, klass, rgctx_info);
- *sp++ = handle_box_from_inst (cfg, val, klass, context_used, data);
- } else {
- *sp++ = handle_box (cfg, val, klass);
- }
+ *sp++ = handle_box (cfg, val, klass, context_used);
CHECK_CFG_EXCEPTION;
ip += 5;
EMIT_NEW_ICONST (cfg, *sp, *((guint32 *)addr));
sp++;
break;
-#ifndef HAVE_MOVING_COLLECTOR
case MONO_TYPE_I:
case MONO_TYPE_U:
+ case MONO_TYPE_PTR:
+ case MONO_TYPE_FNPTR:
+#ifndef HAVE_MOVING_COLLECTOR
case MONO_TYPE_STRING:
case MONO_TYPE_OBJECT:
case MONO_TYPE_CLASS:
case MONO_TYPE_SZARRAY:
- case MONO_TYPE_PTR:
- case MONO_TYPE_FNPTR:
case MONO_TYPE_ARRAY:
+#endif
EMIT_NEW_PCONST (cfg, *sp, *((gpointer *)addr));
type_to_eval_stack_type ((cfg), field->type, *sp);
sp++;
break;
-#endif
case MONO_TYPE_I8:
case MONO_TYPE_U8:
EMIT_NEW_I8CONST (cfg, *sp, *((gint64 *)addr));
allocator because we can't get the
open generic class's vtable. We
have the same problem in
- handle_alloc_from_inst(). This
+ handle_alloc(). This
needs to be solved so that we can
have managed allocs of shared
generic classes. */
}
readonly = FALSE;
- ins = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1]);
+ ins = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], TRUE);
*sp++ = ins;
ip += 5;
break;
MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, index_reg);
EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, ins, &klass->byval_arg, array_reg, offset);
} else {
- addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1]);
+ addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], TRUE);
EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, ins, &klass->byval_arg, addr->dreg, 0);
}
*sp++ = ins;
MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, index_reg);
EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, &klass->byval_arg, array_reg, offset, sp [2]->dreg);
} else {
- addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1]);
+ addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], TRUE);
EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, &klass->byval_arg, addr->dreg, 0, sp [2]->dreg);
}
}
if ((handlers = mono_find_final_block (cfg, ip, target, MONO_EXCEPTION_CLAUSE_FINALLY))) {
GList *tmp;
+ MonoExceptionClause *clause;
+
for (tmp = handlers; tmp; tmp = tmp->next) {
- tblock = tmp->data;
+ clause = tmp->data;
+ tblock = cfg->cil_offset_to_bb [clause->handler_offset];
+ g_assert (tblock);
link_bblock (cfg, bblock, tblock);
MONO_INST_NEW (cfg, ins, OP_CALL_HANDLER);
ins->inst_target_bb = tblock;
+ ins->inst_eh_block = clause;
MONO_ADD_INS (bblock, ins);
bblock->has_call_handler = 1;
if (COMPILE_LLVM (cfg)) {
case OP_LSHR:
case OP_LSHL:
case OP_LSHR_UN:
+ return -1;
#endif
#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_EMULATE_DIV)
case OP_IDIV:
case OP_IDIV_UN:
case OP_IREM:
case OP_IREM_UN:
-#endif
return -1;
+#endif
default:
return mono_op_to_op_imm (opcode);
}