From: Bernhard Urban Date: Tue, 7 Mar 2017 09:46:58 +0000 (+0100) Subject: [interp] implement cee_unbox and cee_ldobj correctly X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=396ea09438b541f2bb793d2ee326fe7ac32b0f56;p=mono.git [interp] implement cee_unbox and cee_ldobj correctly unbox is supposed to push a managed pointer on the stack and ldobj does the actual value copy. unbox_any is basically unbox+ldobj according to the spec. fixes random crashes in test_0_regress_80622:iltests.il --- diff --git a/mono/mini/interp/interp.c b/mono/mini/interp/interp.c index 7092c749b08..d881e23dfab 100644 --- a/mono/mini/interp/interp.c +++ b/mono/mini/interp/interp.c @@ -2767,20 +2767,16 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context) } #endif MINT_IN_CASE(MINT_LDOBJ) { - int size; void *p; c = rtm->data_items[* (guint16 *)(ip + 1)]; ip += 2; - if (c->byval_arg.type != MONO_TYPE_VALUETYPE || c->byval_arg.data.klass->enumtype) { - p = sp [-1].data.p; - stackval_from_data (&c->byval_arg, &sp [-1], p, FALSE); - } else { - size = mono_class_value_size (c, NULL); - p = sp [-1].data.p; + p = sp [-1].data.p; + if (c->byval_arg.type == MONO_TYPE_VALUETYPE && !c->enumtype) { + int size = mono_class_value_size (c, NULL); sp [-1].data.p = vt_sp; - memcpy(vt_sp, p, size); vt_sp += (size + 7) & ~7; } + stackval_from_data (&c->byval_arg, &sp [-1], p, FALSE); MINT_IN_BREAK; } MINT_IN_CASE(MINT_LDSTR) @@ -2919,12 +2915,7 @@ array_constructed: if (!(isinst_obj || ((o->vtable->klass->rank == 0) && (o->vtable->klass->element_class == c->element_class)))) THROW_EX (mono_get_exception_invalid_cast (), ip); - if (c->byval_arg.type == MONO_TYPE_VALUETYPE && !c->enumtype) { - int size = mono_class_native_size (c, NULL); - sp [-1].data.p = vt_sp; - vt_sp += (size + 7) & ~7; - } - stackval_from_data (&c->byval_arg, &sp [-1], mono_object_unbox (o), FALSE); + sp [-1].data.p = mono_object_unbox (o); ip += 2; MINT_IN_BREAK; MINT_IN_CASE(MINT_THROW) diff --git a/mono/mini/interp/transform.c b/mono/mini/interp/transform.c index 7496c18596c..5e2876cd869 100644 --- a/mono/mini/interp/transform.c +++ b/mono/mini/interp/transform.c @@ -1953,7 +1953,11 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo int mt = mint_type (&klass->byval_arg); ADD_CODE (&td, MINT_UNBOX); ADD_CODE (&td, get_data_item_index (&td, klass)); + + ADD_CODE (&td, MINT_LDOBJ); + ADD_CODE (&td, get_data_item_index(&td, klass)); SET_TYPE (td.sp - 1, stack_type [mt], klass); + if (mt == MINT_TYPE_VT) { int size = mono_class_value_size (klass, NULL); PUSH_VT (&td, size);