+2009-02-27 Rodrigo Kumpera <rkumpera@novell.com>
+
+ * icall.c: New icall ves_icall_System_Enum_compare_value_to that
+ helps Enum::CompareTo to be implemented without reboxing all enums
+ to their underlying type.
2009-02-27 Zoltan Varga <vargaz@gmail.com>
* domain.c (SET_APPDOMAIN): Avoid calling TlsSetValue () on some platforms,
ICALL_TYPE(ENUM, "System.Enum", ENUM_1)
ICALL(ENUM_1, "ToObject", ves_icall_System_Enum_ToObject)
+ICALL(ENUM_5, "compare_value_to", ves_icall_System_Enum_compare_value_to)
ICALL(ENUM_4, "get_hashcode", ves_icall_System_Enum_get_hashcode)
ICALL(ENUM_3, "get_underlying_type", ves_icall_System_Enum_get_underlying_type)
ICALL(ENUM_2, "get_value", ves_icall_System_Enum_get_value)
}
static int
+ves_icall_System_Enum_compare_value_to (MonoObject *this, MonoObject *other)
+{
+ gpointer tdata = (char *)this + sizeof (MonoObject);
+ gpointer odata = (char *)other + sizeof (MonoObject);
+ MonoType *basetype = mono_class_enum_basetype (this->vtable->klass);
+ g_assert (basetype);
+
+#define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
+ ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
+ ENUM_TYPE other = *((ENUM_TYPE*)odata); \
+ if (me == other) \
+ return 0; \
+ return me > other ? 1 : -1; \
+ } while (0)
+
+#define COMPARE_ENUM_VALUES_RANGE(ENUM_TYPE) do { \
+ ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
+ ENUM_TYPE other = *((ENUM_TYPE*)odata); \
+ if (me == other) \
+ return 0; \
+ return me - other; \
+ } while (0)
+
+ switch (basetype->type) {
+ case MONO_TYPE_U1:
+ COMPARE_ENUM_VALUES (guint8);
+ case MONO_TYPE_I1:
+ COMPARE_ENUM_VALUES (gint8);
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_U2:
+ COMPARE_ENUM_VALUES_RANGE (guint16);
+ case MONO_TYPE_I2:
+ COMPARE_ENUM_VALUES (gint16);
+ case MONO_TYPE_U4:
+ COMPARE_ENUM_VALUES (guint32);
+ case MONO_TYPE_I4:
+ COMPARE_ENUM_VALUES (gint32);
+ case MONO_TYPE_U8:
+ COMPARE_ENUM_VALUES (guint64);
+ case MONO_TYPE_I8:
+ COMPARE_ENUM_VALUES (gint64);
+ default:
+ g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
+ }
+#undef COMPARE_ENUM_VALUES_RANGE
+#undef COMPARE_ENUM_VALUES
+ return 0;
+}
+
ves_icall_System_Enum_get_hashcode (MonoObject *this)
{
gpointer data = (char *)this + sizeof (MonoObject);