method->hasthis = hasthis;
method->explicit_this = explicit_this;
method->call_convention = call_convention;
+ method->generic_param_count = gen_param_count;
if (call_convention != 0xa)
method->ret = mono_metadata_parse_type (m, MONO_PARSE_RET, ret_attrs, ptr, &ptr);
g_free (sig);
}
-static MonoGenericInst *
-mono_metadata_parse_generic_inst (MonoImage *m, const char *ptr, const char **rptr)
+static void
+do_mono_metadata_parse_generic_inst (MonoType *type, MonoImage *m, const char *ptr, const char **rptr)
{
MonoGenericInst *generic_inst = g_new0 (MonoGenericInst, 1);
int i, count;
+
+ type->data.generic_inst = generic_inst;
generic_inst->generic_type = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
generic_inst->type_argc = count = mono_metadata_decode_value (ptr, &ptr);
generic_inst->type_argv = g_new0 (MonoType*, count);
+ /*
+ * Create the klass before parsing the type arguments.
+ * This is required to support "recursive" definitions.
+ * See mcs/tests/gen-23.cs for an example.
+ */
+
+ generic_inst->klass = mono_class_create_from_generic (m, type);
+
for (i = 0; i < generic_inst->type_argc; i++)
generic_inst->type_argv [i] = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
+ mono_class_initialize_generic (generic_inst->klass, TRUE);
+
+ if (rptr)
+ *rptr = ptr;
+}
+
+static MonoGenericParam *
+mono_metadata_parse_generic_param (MonoImage *m, const char *ptr, const char **rptr)
+{
+ MonoGenericParam *generic_param = g_new0 (MonoGenericParam, 1);
+
+ generic_param->num = mono_metadata_decode_value (ptr, &ptr);
+
if (rptr)
*rptr = ptr;
- return generic_inst;
+ return generic_param;
}
/*
case MONO_TYPE_MVAR:
case MONO_TYPE_VAR:
- type->data.type_param = mono_metadata_decode_value (ptr, &ptr);
+ type->data.generic_param = mono_metadata_parse_generic_param (m, ptr, &ptr);
break;
case MONO_TYPE_GENERICINST:
- type->data.generic_inst = mono_metadata_parse_generic_inst (m, ptr, &ptr);
+ do_mono_metadata_parse_generic_inst (type, m, ptr, &ptr);
break;
default:
return loc.result + 1;
}
+/*
+ * mono_metadata_custom_attrs_from_index:
+ * @meta: metadata context
+ * @index: token representing the parent
+ *
+ * Returns: the 1-based index into the CustomAttribute table of the first
+ * attribute which belongs to the metadata object described by @index.
+ * Returns 0 if no such attribute is found.
+ */
+guint32
+mono_metadata_custom_attrs_from_index (MonoImage *meta, guint32 index)
+{
+ MonoTableInfo *tdef = &meta->tables [MONO_TABLE_CUSTOMATTRIBUTE];
+ locator_t loc;
+
+ if (!tdef->base)
+ return 0;
+
+ loc.idx = index;
+ loc.col_idx = MONO_CUSTOM_ATTR_PARENT;
+ loc.t = tdef;
+
+ if (!bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, table_locator))
+ return 0;
+
+ /* Find the first entry by searching backwards */
+ while ((loc.result > 0) && (mono_metadata_decode_row_col (tdef, loc.result - 1, MONO_CUSTOM_ATTR_PARENT) == index))
+ loc.result --;
+
+ /* loc_result is 0..1, needs to be mapped to table index (that is +1) */
+ return loc.result + 1;
+}
+
#ifdef DEBUG
static void
mono_backtrace (int limit)
*align = __alignof__(gpointer);
return sizeof (gpointer);
case MONO_TYPE_TYPEDBYREF:
- *align = __alignof__(gpointer);
- return sizeof (gpointer) * 2;
+ return mono_class_value_size (mono_defaults.typed_reference_class, align);
case MONO_TYPE_GENERICINST: {
MonoClass *iclass = mono_class_from_mono_type (t);
return mono_type_size (&iclass->byval_arg, align);
}
+ case MONO_TYPE_VAR:
+ case MONO_TYPE_MVAR:
+ *align = __alignof__(gpointer);
+ return sizeof (gpointer);
default:
g_error ("mono_type_size: type 0x%02x unknown", t->type);
}
}
case MONO_TYPE_VAR:
case MONO_TYPE_MVAR:
- return t1->data.type_param == t2->data.type_param;
+ return t1->data.generic_param->num == t2->data.generic_param->num;
default:
g_error ("implement type compare for %0x!", t1->type);
return FALSE;
guint32 len;
MonoType *type;
+ mono_loader_lock ();
+
+ if ((type = g_hash_table_lookup (image->typespec_cache, GUINT_TO_POINTER (type_spec)))) {
+ mono_loader_unlock ();
+ return type;
+ }
+
t = &image->tables [MONO_TABLE_TYPESPEC];
mono_metadata_decode_row (t, idx-1, cols, MONO_TYPESPEC_SIZE);
ptr = mono_metadata_blob_heap (image, cols [MONO_TYPESPEC_SIGNATURE]);
len = mono_metadata_decode_value (ptr, &ptr);
- type = mono_metadata_parse_type (image, MONO_PARSE_TYPE, 0, ptr, &ptr);
+
+ type = g_new0 (MonoType, 1);
+
+ g_hash_table_insert (image->typespec_cache, GUINT_TO_POINTER (type_spec), type);
+
+ if (*ptr == MONO_TYPE_BYREF) {
+ type->byref = 1;
+ ptr++;
+ }
+
+ do_mono_metadata_parse_type (type, image, ptr, &ptr);
+
+ mono_loader_unlock ();
return type;
}
case MONO_NATIVE_BOOLEAN:
*conv = MONO_MARSHAL_CONV_BOOL_I4;
return MONO_NATIVE_BOOLEAN;
+ case MONO_NATIVE_I1:
case MONO_NATIVE_U1:
- return MONO_NATIVE_U1;
+ return mspec->native;
default:
g_error ("cant marshal bool to native type %02x", mspec->native);
}
n = 1;
do {
params = g_realloc (params, sizeof (MonoGenericParam) * n);
+ params [n - 1].pklass = NULL;
+ params [n - 1].method = NULL;
params [n - 1].flags = cols [MONO_GENERICPARAM_FLAGS];
params [n - 1].num = cols [MONO_GENERICPARAM_NUMBER];
params [n - 1].name = mono_metadata_string_heap (image, cols [MONO_GENERICPARAM_NAME]);
params [n - 1].constraints = get_constraints (image, i + 1);
- i++;
+ if (++i >= tdef->rows)
+ break;
mono_metadata_decode_row (tdef, i, cols, MONO_GENERICPARAM_SIZE);
- } while (cols [MONO_GENERICPARAM_NUMBER] == last_num + 1);
+ n++;
+ } while (cols [MONO_GENERICPARAM_OWNER] == owner);
if (num)
*num = n;