{
guint32 bitfield = t->size_bitfield;
int i, count = mono_metadata_table_count (bitfield);
- const char *data = t->base + idx * t->row_size;
+ const char *data;
+
+ g_assert (idx < t->rows);
+ data = t->base + idx * t->row_size;
g_assert (res_size == count);
{
guint32 bitfield = t->size_bitfield;
int i;
- register const char *data = t->base + idx * t->row_size;
+ register const char *data;
register int n;
+ g_assert (idx < t->rows);
g_assert (col < mono_metadata_table_count (bitfield));
+ data = t->base + idx * t->row_size;
n = mono_metadata_table_size (bitfield, 0);
for (i = 0; i < col; ++i) {
}
static gboolean
-mono_generic_inst_equal (gconstpointer ka, gconstpointer kb)
+mono_generic_inst_equal_full (const MonoGenericInst *a, const MonoGenericInst *b, gboolean signature_only)
{
- const MonoGenericInst *a = (const MonoGenericInst *) ka;
- const MonoGenericInst *b = (const MonoGenericInst *) kb;
int i;
+ if (a->id && b->id) {
+ if (a->id == b->id)
+ return TRUE;
+ if (!signature_only)
+ return FALSE;
+ }
+
if (a->is_open != b->is_open || a->type_argc != b->type_argc)
return FALSE;
for (i = 0; i < a->type_argc; ++i) {
- if (!do_mono_metadata_type_equal (a->type_argv [i], b->type_argv [i], FALSE))
+ if (!do_mono_metadata_type_equal (a->type_argv [i], b->type_argv [i], signature_only))
return FALSE;
}
return TRUE;
}
+static gboolean
+mono_generic_inst_equal (gconstpointer ka, gconstpointer kb)
+{
+ const MonoGenericInst *a = (const MonoGenericInst *) ka;
+ const MonoGenericInst *b = (const MonoGenericInst *) kb;
+
+ return mono_generic_inst_equal_full (a, b, FALSE);
+}
+
static guint
mono_generic_class_hash (gconstpointer data)
{
goto retry;
case MONO_TYPE_FNPTR:
return signature_in_image (type->data.method, image);
+ case MONO_TYPE_VAR:
+ if (type->data.generic_param->owner) {
+ g_assert (!type->data.generic_param->owner->is_method);
+ return type->data.generic_param->owner->owner.klass->image == image;
+ } else {
+ return type->data.generic_param->image == image;
+ }
+ case MONO_TYPE_MVAR:
+ if (type->data.generic_param->owner) {
+ g_assert (type->data.generic_param->owner->is_method);
+ if (!type->data.generic_param->owner->owner.method)
+ /* RefEmit created generic param whose method is not finished */
+ return FALSE;
+ return type->data.generic_param->owner->owner.method->klass->image == image;
+ } else {
+ return type->data.generic_param->image == image;
+ }
default:
/* At this point, we should've avoided all potential allocations in mono_class_from_mono_type () */
return image == mono_class_from_mono_type (type)->image;
param->name = mono_mempool_alloc0 (m->mempool, 8);
sprintf ((char*)param->name, "%d", index);
param->num = index;
+ param->image = m;
return param;
}
*/
int
mono_type_stack_size (MonoType *t, int *align)
+{
+ return mono_type_stack_size_internal (t, align, FALSE);
+}
+
+int
+mono_type_stack_size_internal (MonoType *t, int *align, gboolean allow_open)
{
int tmp;
guint32 size;
if (t->data.klass->enumtype)
- return mono_type_stack_size (t->data.klass->enum_basetype, align);
+ return mono_type_stack_size_internal (t->data.klass->enum_basetype, align, allow_open);
else {
size = mono_class_value_size (t->data.klass, (guint32*)align);
MonoGenericClass *gclass = t->data.generic_class;
MonoClass *container_class = gclass->container_class;
- g_assert (!gclass->context.class_inst->is_open);
+ if (!allow_open)
+ g_assert (!gclass->context.class_inst->is_open);
if (container_class->valuetype) {
if (container_class->enumtype)
- return mono_type_stack_size (container_class->enum_basetype, align);
+ return mono_type_stack_size_internal (container_class->enum_basetype, align, allow_open);
else {
guint32 size = mono_class_value_size (mono_class_from_mono_type (t), (guint32*)align);
static gboolean
_mono_metadata_generic_class_equal (const MonoGenericClass *g1, const MonoGenericClass *g2, gboolean signature_only)
{
- int i;
MonoGenericInst *i1 = g1->context.class_inst;
MonoGenericInst *i2 = g2->context.class_inst;
- if (i1->type_argc != i2->type_argc || g1->is_dynamic != g2->is_dynamic)
+ if (g1->is_dynamic != g2->is_dynamic)
return FALSE;
if (!mono_metadata_class_equal (g1->container_class, g2->container_class, signature_only))
return FALSE;
- for (i = 0; i < i1->type_argc; ++i) {
- if (!do_mono_metadata_type_equal (i1->type_argv [i], i2->type_argv [i], signature_only))
- return FALSE;
- }
+ if (!mono_generic_inst_equal_full (i1, i2, signature_only))
+ return FALSE;
return g1->is_tb_open == g2->is_tb_open;
}
+static gboolean
+_mono_metadata_generic_class_container_equal (const MonoGenericClass *g1, MonoClass *c2, gboolean signature_only)
+{
+ MonoGenericInst *i1 = g1->context.class_inst;
+ MonoGenericInst *i2 = c2->generic_container->context.class_inst;
+
+ if (!mono_metadata_class_equal (g1->container_class, c2, signature_only))
+ return FALSE;
+ if (!mono_generic_inst_equal_full (i1, i2, signature_only))
+ return FALSE;
+ return !g1->is_tb_open;
+}
+
guint
mono_metadata_generic_context_hash (const MonoGenericContext *context)
{
return TRUE;
if (c1->generic_class && c2->generic_class)
return _mono_metadata_generic_class_equal (c1->generic_class, c2->generic_class, signature_only);
+ if (c1->generic_class && c2->generic_container)
+ return _mono_metadata_generic_class_container_equal (c1->generic_class, c2, signature_only);
+ if (c1->generic_container && c2->generic_class)
+ return _mono_metadata_generic_class_container_equal (c2->generic_class, c1, signature_only);
if ((c1->byval_arg.type == MONO_TYPE_VAR) && (c2->byval_arg.type == MONO_TYPE_VAR))
return mono_metadata_generic_param_equal (
c1->byval_arg.data.generic_param, c2->byval_arg.data.generic_param, signature_only);
return do_mono_metadata_type_equal (t1, t2, FALSE);
}
+/**
+ * mono_metadata_type_equal_full:
+ * @t1: a type
+ * @t2: another type
+ * @signature_only: if signature only comparison should be made
+ *
+ * Determine if @t1 and @t2 are signature compatible if @signature_only is #TRUE, otherwise
+ * behaves the same way as mono_metadata_type_equal.
+ * The function mono_metadata_type_equal(a, b) is just a shortcut for mono_metadata_type_equal_full(a, b, FALSE).
+ * Returns: #TRUE if @t1 and @t2 are equal taking @signature_only into account.
+ */
+gboolean
+mono_metadata_type_equal_full (MonoType *t1, MonoType *t2, gboolean signature_only)
+{
+ return do_mono_metadata_type_equal (t1, t2, signature_only);
+}
+
/**
* mono_metadata_signature_equal:
* @sig1: a signature