Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mono/mini/interp/interp.c49
-rw-r--r--mono/mini/interp/mintops.def21
-rw-r--r--mono/mini/interp/transform.c32
3 files changed, 98 insertions, 4 deletions
diff --git a/mono/mini/interp/interp.c b/mono/mini/interp/interp.c
index 02526ec2705..2c2ab929eba 100644
--- a/mono/mini/interp/interp.c
+++ b/mono/mini/interp/interp.c
@@ -4468,6 +4468,31 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st
++sp;
MINT_IN_BREAK;
}
+
+/* We init class here to preserve cctor order */
+#define LDSFLD(datamem, fieldtype) { \
+ MonoVTable *vtable = (MonoVTable*) rtm->data_items [*(guint16*)(ip + 1)]; \
+ if (G_UNLIKELY (!vtable->initialized)) { \
+ mono_runtime_class_init_full (vtable, error); \
+ if (!mono_error_ok (error)) \
+ THROW_EX (mono_error_convert_to_exception (error), ip); \
+ } \
+ sp[0].data.datamem = * (fieldtype *)(rtm->data_items [* (guint16 *)(ip + 2)]) ; \
+ ip += 3; \
+ sp++; \
+ }
+
+ MINT_IN_CASE(MINT_LDSFLD_I1) LDSFLD(i, gint8); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_U1) LDSFLD(i, guint8); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_I2) LDSFLD(i, gint16); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_U2) LDSFLD(i, guint16); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_I4) LDSFLD(i, gint32); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_I8) LDSFLD(l, gint64); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_R4) LDSFLD(f_r4, float); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_R8) LDSFLD(f, double); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_O) LDSFLD(p, gpointer); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LDSFLD_P) LDSFLD(p, gpointer); MINT_IN_BREAK;
+
MINT_IN_CASE(MINT_LDSFLD) {
MonoClassField *field = (MonoClassField*)rtm->data_items [* (guint16 *)(ip + 1)];
gpointer addr = mono_class_static_field_address (rtm->domain, field);
@@ -4490,6 +4515,30 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, guint16 *st
++sp;
MINT_IN_BREAK;
}
+
+#define STSFLD(datamem, fieldtype) { \
+ MonoVTable *vtable = (MonoVTable*) rtm->data_items [*(guint16*)(ip + 1)]; \
+ if (G_UNLIKELY (!vtable->initialized)) { \
+ mono_runtime_class_init_full (vtable, error); \
+ if (!mono_error_ok (error)) \
+ THROW_EX (mono_error_convert_to_exception (error), ip); \
+ } \
+ sp --; \
+ * (fieldtype *)(rtm->data_items [* (guint16 *)(ip + 2)]) = sp[0].data.datamem; \
+ ip += 3; \
+ }
+
+ MINT_IN_CASE(MINT_STSFLD_I1) STSFLD(i, gint8); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_U1) STSFLD(i, guint8); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_I2) STSFLD(i, gint16); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_U2) STSFLD(i, guint16); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_I4) STSFLD(i, gint32); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_I8) STSFLD(l, gint64); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_R4) STSFLD(f_r4, float); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_R8) STSFLD(f, double); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_P) STSFLD(p, gpointer); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_STSFLD_O) STSFLD(p, gpointer); MINT_IN_BREAK;
+
MINT_IN_CASE(MINT_STSFLD) {
MonoClassField *field = (MonoClassField*)rtm->data_items [* (guint16 *)(ip + 1)];
gpointer addr = mono_class_static_field_address (rtm->domain, field);
diff --git a/mono/mini/interp/mintops.def b/mono/mini/interp/mintops.def
index 21d16b2cfa8..33fca0240d6 100644
--- a/mono/mini/interp/mintops.def
+++ b/mono/mini/interp/mintops.def
@@ -114,8 +114,29 @@ OPDEF(MINT_STRMFLD, "strmfld", 2, MintOpFieldToken)
OPDEF(MINT_STRMFLD_VT, "strmfld.vt", 2, MintOpUShortInt)
OPDEF(MINT_LDSFLD, "ldsfld", 2, MintOpFieldToken)
+OPDEF(MINT_LDSFLD_I1, "ldsfld.i1", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_U1, "ldsfld.u1", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_I2, "ldsfld.i2", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_U2, "ldsfld.u2", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_I4, "ldsfld.i4", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_I8, "ldsfld.i8", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_R4, "ldsfld.r4", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_R8, "ldsfld.r8", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_O, "ldsfld.o", 3, MintOpUShortInt)
+OPDEF(MINT_LDSFLD_P, "ldsfld.p", 3, MintOpUShortInt)
OPDEF(MINT_LDSFLD_VT, "ldsfld.vt", 4, MintOpShortAndInt)
+
OPDEF(MINT_STSFLD, "stsfld", 2, MintOpUShortInt)
+OPDEF(MINT_STSFLD_I1, "stsfld.i1", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_U1, "stsfld.u1", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_I2, "stsfld.i2", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_U2, "stsfld.u2", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_I4, "stsfld.i4", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_I8, "stsfld.i8", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_R4, "stsfld.r4", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_R8, "stsfld.r8", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_O, "stsfld.o", 3, MintOpUShortInt)
+OPDEF(MINT_STSFLD_P, "stsfld.p", 3, MintOpUShortInt)
OPDEF(MINT_STSFLD_VT, "stsfld.vt", 2, MintOpUShortInt)
OPDEF(MINT_LDSFLDA, "ldsflda", 2, MintOpUShortInt)
diff --git a/mono/mini/interp/transform.c b/mono/mini/interp/transform.c
index 8f7c9ac8959..6a336c99684 100644
--- a/mono/mini/interp/transform.c
+++ b/mono/mini/interp/transform.c
@@ -3636,15 +3636,26 @@ generate (MonoMethod *method, MonoMethodHeader *header, InterpMethod *rtm, unsig
goto_if_nok (error, exit);
MonoType *ftype = mono_field_get_type (field);
mt = mint_type (ftype);
- ADD_CODE(td, mt == MINT_TYPE_VT ? MINT_LDSFLD_VT : MINT_LDSFLD);
- ADD_CODE(td, get_data_item_index (td, field));
klass = NULL;
if (mt == MINT_TYPE_VT) {
+ ADD_CODE(td, MINT_LDSFLD_VT);
+ ADD_CODE(td, get_data_item_index (td, field));
klass = mono_class_from_mono_type (ftype);
int size = mono_class_value_size (klass, NULL);
PUSH_VT(td, size);
WRITE32(td, &size);
} else {
+ if (mono_class_field_is_special_static (field)) {
+ ADD_CODE(td, MINT_LDSFLD);
+ ADD_CODE(td, get_data_item_index (td, field));
+ } else {
+ MonoVTable *vtable = mono_class_vtable_checked (domain, field->parent, error);
+ goto_if_nok (error, exit);
+
+ ADD_CODE(td, MINT_LDSFLD_I1 + mt - MINT_TYPE_I1);
+ ADD_CODE(td, get_data_item_index (td, vtable));
+ ADD_CODE(td, get_data_item_index (td, (char*)mono_vtable_get_static_field_data (vtable) + field->offset));
+ }
if (mt == MINT_TYPE_O)
klass = mono_class_from_mono_type (ftype);
}
@@ -3659,8 +3670,6 @@ generate (MonoMethod *method, MonoMethodHeader *header, InterpMethod *rtm, unsig
goto_if_nok (error, exit);
MonoType *ftype = mono_field_get_type (field);
mt = mint_type (ftype);
- ADD_CODE(td, mt == MINT_TYPE_VT ? MINT_STSFLD_VT : MINT_STSFLD);
- ADD_CODE(td, get_data_item_index (td, field));
/* the vtable of the field might not be initialized at this point */
MonoClass *fld_klass = mono_class_from_mono_type (field->type);
@@ -3670,7 +3679,22 @@ generate (MonoMethod *method, MonoMethodHeader *header, InterpMethod *rtm, unsig
if (mt == MINT_TYPE_VT) {
MonoClass *klass = mono_class_from_mono_type (ftype);
int size = mono_class_value_size (klass, NULL);
+ ADD_CODE(td, MINT_STSFLD_VT);
+ ADD_CODE(td, get_data_item_index (td, field));
POP_VT (td, size);
+ } else {
+ if (mono_class_field_is_special_static (field)) {
+ ADD_CODE(td, MINT_STSFLD);
+ ADD_CODE(td, get_data_item_index (td, field));
+ } else {
+ MonoVTable *vtable = mono_class_vtable_checked (domain, field->parent, error);
+ goto_if_nok (error, exit);
+
+ ADD_CODE(td, MINT_STSFLD_I1 + mt - MINT_TYPE_I1);
+ ADD_CODE(td, get_data_item_index (td, vtable));
+ ADD_CODE(td, get_data_item_index (td, (char*)mono_vtable_get_static_field_data (vtable) + field->offset));
+ }
+
}
td->ip += 5;
--td->sp;