[interpreter] implement {st,ld}elem for value types
authorBernhard Urban <bernhard.urban@xamarin.com>
Thu, 9 Feb 2017 19:42:18 +0000 (20:42 +0100)
committerBernhard Urban <bernhard.urban@xamarin.com>
Thu, 16 Feb 2017 22:09:38 +0000 (23:09 +0100)
mono/mini/interpreter/interp.c
mono/mini/interpreter/mintops.def
mono/mini/interpreter/transform.c

index e4cd5e074e20b7bc8d47a94cbed3d1f93f896a53..26e7de88809993f771f1a2cbe71b541468bed12b 100644 (file)
@@ -3214,7 +3214,8 @@ array_constructed:
                MINT_IN_CASE(MINT_LDELEM_I)  /* fall through */
                MINT_IN_CASE(MINT_LDELEM_R4) /* fall through */
                MINT_IN_CASE(MINT_LDELEM_R8) /* fall through */
-               MINT_IN_CASE(MINT_LDELEM_REF) {
+               MINT_IN_CASE(MINT_LDELEM_REF) /* fall through */
+               MINT_IN_CASE(MINT_LDELEM_VT) {
                        MonoArray *o;
                        mono_u aindex;
 
@@ -3265,6 +3266,16 @@ array_constructed:
                        case MINT_LDELEM_REF:
                                sp [0].data.p = mono_array_get (o, gpointer, aindex);
                                break;
+                       case MINT_LDELEM_VT: {
+                               MonoClass *klass_vt = rtm->data_items [*(guint16 *) (ip + 1)];
+                               i32 = READ32 (ip + 2);
+                               char *src_addr = mono_array_addr_with_size ((MonoArray *) o, i32, aindex);
+                               sp [0].data.vt = vt_sp;
+                               stackval_from_data (&klass_vt->byval_arg, sp, src_addr, FALSE);
+                               vt_sp += (i32 + 7) & ~7;
+                               ip += 3;
+                               break;
+                       }
                        default:
                                ves_abort();
                        }
@@ -3280,7 +3291,8 @@ array_constructed:
                MINT_IN_CASE(MINT_STELEM_I8) /* fall through */
                MINT_IN_CASE(MINT_STELEM_R4) /* fall through */
                MINT_IN_CASE(MINT_STELEM_R8) /* fall through */
-               MINT_IN_CASE(MINT_STELEM_REF) {
+               MINT_IN_CASE(MINT_STELEM_REF) /* fall through */
+               MINT_IN_CASE(MINT_STELEM_VT) {
                        mono_u aindex;
 
                        sp -= 3;
@@ -3321,7 +3333,18 @@ array_constructed:
                                if (sp [2].data.p && !isinst_obj)
                                        THROW_EX (mono_get_exception_array_type_mismatch (), ip);
                                mono_array_set ((MonoArray *)o, gpointer, aindex, sp [2].data.p);
-                       } break;
+                               break;
+                       }
+                       case MINT_STELEM_VT: {
+                               MonoClass *klass_vt = rtm->data_items [*(guint16 *) (ip + 1)];
+                               i32 = READ32 (ip + 2);
+                               char *dst_addr = mono_array_addr_with_size ((MonoArray *) o, i32, aindex);
+
+                               stackval_to_data (&klass_vt->byval_arg, &sp [2], dst_addr, FALSE);
+                               vt_sp -= (i32 + 7) & ~7;
+                               ip += 3;
+                               break;
+                       }
                        default:
                                ves_abort();
                        }
index 28b1c400b9636f75dbf5123201ec2aeccc5d7a7d..a9ed29f4ae39681b912dda78c0c5d5e2a40c240f 100644 (file)
@@ -295,6 +295,7 @@ OPDEF(MINT_LDELEM_I8, "ldelem.i8", 1, MintOpNoArgs)
 OPDEF(MINT_LDELEM_R4, "ldelem.r4", 1, MintOpNoArgs)
 OPDEF(MINT_LDELEM_R8, "ldelem.r8", 1, MintOpNoArgs)
 OPDEF(MINT_LDELEM_REF, "ldelem.ref", 1, MintOpNoArgs)
+OPDEF(MINT_LDELEM_VT, "ldelem.vt", 4, MintOpShortAndInt)
 
 OPDEF(MINT_LDELEMA, "ldelema", 2, MintOpClassToken)
 
@@ -306,6 +307,7 @@ OPDEF(MINT_STELEM_I8, "stelem.i8", 1, MintOpNoArgs)
 OPDEF(MINT_STELEM_R4, "stelem.r4", 1, MintOpNoArgs)
 OPDEF(MINT_STELEM_R8, "stelem.r8", 1, MintOpNoArgs)
 OPDEF(MINT_STELEM_REF, "stelem.ref", 1, MintOpNoArgs)
+OPDEF(MINT_STELEM_VT, "stelem.vt", 4, MintOpShortAndInt)
 
 OPDEF(MINT_LDLEN, "ldlen", 1, MintOpNoArgs)
 
index dafefb4eea9c7c401508c1e9fc08ef7873995662..49fa853a7ff54392a5b000f120bc7ffdc60b5998 100644 (file)
@@ -2199,6 +2199,17 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start)
                                        --td.sp;
                                        SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4);
                                        break;
+                               case MINT_TYPE_VT: {
+                                       int size = mono_class_value_size (klass, NULL);
+                                       ENSURE_I4 (&td, 1);
+                                       SIMPLE_OP (td, MINT_LDELEM_VT);
+                                       ADD_CODE (&td, get_data_item_index (&td, klass));
+                                       WRITE32 (&td, &size);
+                                       --td.sp;
+                                       SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_VT);
+                                       PUSH_VT (&td, size);
+                                       break;
+                               }
                                default: {
                                        GString *res = g_string_new ("");
                                        mono_type_get_desc (res, &klass->byval_arg, TRUE);
@@ -2267,6 +2278,17 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start)
                                case MINT_TYPE_I4:
                                        SIMPLE_OP (td, MINT_STELEM_I4);
                                        break;
+                               case MINT_TYPE_O:
+                                       SIMPLE_OP (td, MINT_STELEM_REF);
+                                       break;
+                               case MINT_TYPE_VT: {
+                                       int size = mono_class_value_size (klass, NULL);
+                                       SIMPLE_OP (td, MINT_STELEM_VT);
+                                       ADD_CODE (&td, get_data_item_index (&td, klass));
+                                       WRITE32 (&td, &size);
+                                       POP_VT (&td, size);
+                                       break;
+                               }
                                default: {
                                        GString *res = g_string_new ("");
                                        mono_type_get_desc (res, &klass->byval_arg, TRUE);