#include "private.h"
#include "class.h"
-static void do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer *generic_container,
+static void do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContext *generic_context,
const char *ptr, const char **rptr);
static gboolean do_mono_metadata_type_equal (MonoType *t1, MonoType *t2, gboolean signature_only);
-static gboolean _mono_metadata_generic_class_equal (MonoGenericClass *g1, MonoGenericClass *g2,
+static gboolean mono_metadata_class_equal (MonoClass *c1, MonoClass *c2, gboolean signature_only);
+static gboolean _mono_metadata_generic_class_equal (const MonoGenericClass *g1, const MonoGenericClass *g2,
gboolean signature_only);
/*
* and dimensions.
*/
MonoArrayType *
-mono_metadata_parse_array_full (MonoImage *m, MonoGenericContainer *generic_container,
+mono_metadata_parse_array_full (MonoImage *m, MonoGenericContext *generic_context,
const char *ptr, const char **rptr)
{
int i;
MonoArrayType *array = g_new0 (MonoArrayType, 1);
MonoType *etype;
- etype = mono_metadata_parse_type_full (m, generic_container, MONO_PARSE_TYPE, 0, ptr, &ptr);
+ etype = mono_metadata_parse_type_full (m, generic_context, MONO_PARSE_TYPE, 0, ptr, &ptr);
array->eklass = mono_class_from_mono_type (etype);
array->rank = mono_metadata_decode_value (ptr, &ptr);
* private static
* private static literal
*/
-static MonoType
+static const MonoType
builtin_types[] = {
/* data, attrs, type, nmods, byref, pinned */
{{NULL}, 0, MONO_TYPE_VOID, 0, 0, 0},
mono_generic_class_hash (gconstpointer data)
{
const MonoGenericClass *gclass = (const MonoGenericClass *) data;
- return mono_metadata_type_hash (gclass->generic_type);
+ return mono_metadata_type_hash (&gclass->container_class->byval_arg);
}
static gboolean
generic_class_cache = g_hash_table_new (mono_generic_class_hash, mono_generic_class_equal);
for (i = 0; i < NBUILTIN_TYPES (); ++i)
- g_hash_table_insert (type_cache, &builtin_types [i], &builtin_types [i]);
+ g_hash_table_insert (type_cache, (gpointer) &builtin_types [i], (gpointer) &builtin_types [i]);
}
/**
* Returns: a #MonoType structure representing the decoded type.
*/
MonoType*
-mono_metadata_parse_type_full (MonoImage *m, MonoGenericContainer *generic_container, MonoParseTypeMode mode,
+mono_metadata_parse_type_full (MonoImage *m, MonoGenericContext *generic_context, MonoParseTypeMode mode,
short opt_attrs, const char *ptr, const char **rptr)
{
MonoType *type, *cached;
type->byref = byref;
type->pinned = pinned ? 1 : 0;
- do_mono_metadata_parse_type (type, m, generic_container, ptr, &ptr);
+ do_mono_metadata_parse_type (type, m, generic_context, ptr, &ptr);
if (rptr)
*rptr = ptr;
* Returns: a MonoMethodSignature describing the signature.
*/
MonoMethodSignature *
-mono_metadata_parse_signature_full (MonoImage *image, MonoGenericContainer *generic_container, guint32 token)
+mono_metadata_parse_signature_full (MonoImage *image, MonoGenericContext *generic_context, guint32 token)
{
MonoTableInfo *tables = image->tables;
guint32 idx = mono_metadata_token_index (token);
ptr = mono_metadata_blob_heap (image, sig);
mono_metadata_decode_blob_size (ptr, &ptr);
- return mono_metadata_parse_method_signature_full (image, generic_container, FALSE, ptr, NULL);
+ return mono_metadata_parse_method_signature_full (image, generic_context, FALSE, ptr, NULL);
}
MonoMethodSignature *
* Returns: a MonoMethodSignature describing the signature.
*/
MonoMethodSignature *
-mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *generic_container,
+mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContext *generic_context,
int def, const char *ptr, const char **rptr)
{
MonoMethodSignature *method;
guint32 hasthis = 0, explicit_this = 0, call_convention, param_count;
guint32 gen_param_count = 0;
gboolean is_open = FALSE;
- MonoGenericContainer *container = NULL;
+ MonoGenericContext *context = NULL;
if (*ptr & 0x10)
gen_param_count = 1;
if (gen_param_count)
method->has_type_parameters = 1;
- if (gen_param_count && (!generic_container || !generic_container->is_method)) {
- container = g_new0 (MonoGenericContainer, 1);
- container->parent = generic_container;
+ if (gen_param_count && (!generic_context || !generic_context->container->is_method)) {
+ MonoGenericContainer *container = g_new0 (MonoGenericContainer, 1);
+
+ if (generic_context)
+ container->parent = generic_context->container;
container->is_signature = 1;
- container->context = g_new0 (MonoGenericContext, 1);
- container->context->container = container;
+ context = &container->context;
+ container->context.container = container;
container->type_argc = gen_param_count;
container->type_params = g_new0 (MonoGenericParam, gen_param_count);
container->type_params [i].num = i;
}
} else
- container = generic_container;
+ context = generic_context;
if (call_convention != 0xa) {
- method->ret = mono_metadata_parse_type_full (m, container, MONO_PARSE_RET, ret_attrs, ptr, &ptr);
+ method->ret = mono_metadata_parse_type_full (m, context, MONO_PARSE_RET, ret_attrs, ptr, &ptr);
is_open = mono_class_is_open_constructed_type (method->ret);
}
ptr++;
}
method->params [i] = mono_metadata_parse_type_full (
- m, container, MONO_PARSE_PARAM, pattrs [i], ptr, &ptr);
+ m, context, MONO_PARSE_PARAM, pattrs [i], ptr, &ptr);
if (!is_open)
is_open = mono_class_is_open_constructed_type (method->params [i]);
}
}
MonoGenericInst *
-mono_metadata_parse_generic_inst (MonoImage *m, MonoGenericContainer *generic_container,
+mono_metadata_parse_generic_inst (MonoImage *m, MonoGenericContext *generic_context,
int count, const char *ptr, const char **rptr)
{
MonoGenericInst *ginst;
ginst->type_argv = g_new0 (MonoType*, count);
for (i = 0; i < ginst->type_argc; i++) {
- MonoType *t = mono_metadata_parse_type_full (m, generic_container, MONO_PARSE_TYPE, 0, ptr, &ptr);
+ MonoType *t = mono_metadata_parse_type_full (m, generic_context, MONO_PARSE_TYPE, 0, ptr, &ptr);
ginst->type_argv [i] = t;
if (!ginst->is_open)
}
static void
-do_mono_metadata_parse_generic_class (MonoType *type, MonoImage *m, MonoGenericContainer *generic_container,
+do_mono_metadata_parse_generic_class (MonoType *type, MonoImage *m, MonoGenericContext *generic_context,
const char *ptr, const char **rptr)
{
MonoGenericClass *gclass = g_new0 (MonoGenericClass, 1);
+ MonoGenericContainer *container;
MonoGenericClass *cached;
MonoGenericInst *ginst;
MonoClass *gklass;
+ MonoType *gtype;
int i, count;
type->data.generic_class = gclass;
gclass->klass = g_new0 (MonoClass, 1);
- gclass->generic_type = mono_metadata_parse_type_full (m, generic_container, MONO_PARSE_TYPE, 0, ptr, &ptr);
-
- gklass = mono_class_from_mono_type (gclass->generic_type);
- g_assert ((gclass->container = gklass->generic_container) != NULL);
+ gtype = mono_metadata_parse_type_full (m, generic_context, MONO_PARSE_TYPE, 0, ptr, &ptr);
+ gclass->container_class = gklass = mono_class_from_mono_type (gtype);
+ g_assert ((gclass->context->container = gklass->generic_container) != NULL);
count = mono_metadata_decode_value (ptr, &ptr);
/*
mono_class_create_generic (gclass);
- gclass->inst = mono_metadata_parse_generic_inst (m, generic_container, count, ptr, &ptr);
+ gclass->inst = mono_metadata_parse_generic_inst (m, generic_context, count, ptr, &ptr);
mono_class_create_generic_2 (gclass);
* Internal routine to parse a generic type parameter.
*/
static MonoGenericParam *
-mono_metadata_parse_generic_param (MonoImage *m, MonoGenericContainer *generic_container,
+mono_metadata_parse_generic_param (MonoImage *m, MonoGenericContext *generic_context,
gboolean is_mvar, const char *ptr, const char **rptr)
{
+ MonoGenericContainer *generic_container;
int index;
index = mono_metadata_decode_value (ptr, &ptr);
if (rptr)
*rptr = ptr;
+ g_assert (generic_context);
+ if (generic_context->gmethod)
+ generic_container = generic_context->gmethod->container;
+ else if (generic_context->gclass)
+ generic_container = generic_context->gclass->container_class->generic_container;
+ else
+ generic_container = generic_context->container;
+
if (!is_mvar) {
g_assert (generic_container);
if (generic_container->parent) {
* This extracts a Type as specified in Partition II (22.2.12)
*/
static void
-do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer *generic_container,
+do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContext *generic_context,
const char *ptr, const char **rptr)
{
type->type = mono_metadata_decode_value (ptr, &ptr);
break;
}
case MONO_TYPE_SZARRAY: {
- MonoType *etype = mono_metadata_parse_type_full (m, generic_container, MONO_PARSE_MOD_TYPE, 0, ptr, &ptr);
+ MonoType *etype = mono_metadata_parse_type_full (m, generic_context, MONO_PARSE_MOD_TYPE, 0, ptr, &ptr);
type->data.klass = mono_class_from_mono_type (etype);
mono_metadata_free_type (etype);
break;
}
case MONO_TYPE_PTR:
- type->data.type = mono_metadata_parse_type_full (m, generic_container, MONO_PARSE_MOD_TYPE, 0, ptr, &ptr);
+ type->data.type = mono_metadata_parse_type_full (m, generic_context, MONO_PARSE_MOD_TYPE, 0, ptr, &ptr);
break;
case MONO_TYPE_FNPTR:
- type->data.method = mono_metadata_parse_method_signature_full (m, generic_container, 0, ptr, &ptr);
+ type->data.method = mono_metadata_parse_method_signature_full (m, generic_context, 0, ptr, &ptr);
break;
case MONO_TYPE_ARRAY:
- type->data.array = mono_metadata_parse_array_full (m, generic_container, ptr, &ptr);
+ type->data.array = mono_metadata_parse_array_full (m, generic_context, ptr, &ptr);
break;
case MONO_TYPE_MVAR:
- type->data.generic_param = mono_metadata_parse_generic_param (m, generic_container, TRUE, ptr, &ptr);
+ type->data.generic_param = mono_metadata_parse_generic_param (m, generic_context, TRUE, ptr, &ptr);
break;
case MONO_TYPE_VAR:
- type->data.generic_param = mono_metadata_parse_generic_param (m, generic_container, FALSE, ptr, &ptr);
+ type->data.generic_param = mono_metadata_parse_generic_param (m, generic_context, FALSE, ptr, &ptr);
break;
case MONO_TYPE_GENERICINST:
- do_mono_metadata_parse_generic_class (type, m, generic_container, ptr, &ptr);
+ do_mono_metadata_parse_generic_class (type, m, generic_context, ptr, &ptr);
break;
default:
* Returns: a MonoMethodHeader.
*/
MonoMethodHeader *
-mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *generic_container, const char *ptr)
+mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContext *generic_context, const char *ptr)
{
MonoMethodHeader *mh;
unsigned char flags = *(const unsigned char *) ptr;
mh->num_locals = len;
for (i = 0; i < len; ++i)
mh->locals [i] = mono_metadata_parse_type_full (
- m, generic_container, MONO_PARSE_LOCAL, 0, locals_ptr, &locals_ptr);
+ m, generic_context, MONO_PARSE_LOCAL, 0, locals_ptr, &locals_ptr);
} else {
mh = g_new0 (MonoMethodHeader, 1);
}
g_assert (!gclass->inst->is_open && !gclass->klass->generic_container);
- if (MONO_TYPE_ISSTRUCT (gclass->generic_type)) {
- MonoClass *gklass = mono_class_from_mono_type (gclass->generic_type);
-
- if (gklass->enumtype)
- return mono_type_size (gklass->enum_basetype, align);
+ if (gclass->container_class->valuetype) {
+ if (gclass->container_class->enumtype)
+ return mono_type_size (gclass->container_class->enum_basetype, align);
else
return mono_class_value_size (gclass->klass, align);
} else {
g_assert (!gclass->inst->is_open && !gclass->klass->generic_container);
- if (MONO_TYPE_ISSTRUCT (gclass->generic_type)) {
- MonoClass *gklass = mono_class_from_mono_type (gclass->generic_type);
-
- if (gklass->enumtype)
- return mono_type_stack_size (gklass->enum_basetype, align);
+ if (gclass->container_class->valuetype) {
+ if (gclass->container_class->enumtype)
+ return mono_type_stack_size (gclass->container_class->enum_basetype, align);
else {
guint32 size = mono_class_value_size (gclass->klass, align);
gboolean
mono_metadata_generic_class_is_valuetype (MonoGenericClass *gclass)
{
- return MONO_TYPE_ISSTRUCT (gclass->generic_type);
+ return gclass->container_class->valuetype;
}
static gboolean
-_mono_metadata_generic_class_equal (MonoGenericClass *g1, MonoGenericClass *g2, gboolean signature_only)
+_mono_metadata_generic_class_equal (const MonoGenericClass *g1, const MonoGenericClass *g2, gboolean signature_only)
{
int i;
- if (g1->inst->type_argc != g2->inst->type_argc)
+ if ((g1->inst->type_argc != g2->inst->type_argc) || (g1->is_dynamic != g2->is_dynamic))
return FALSE;
- if (!do_mono_metadata_type_equal (g1->generic_type, g2->generic_type, signature_only))
+ if (!mono_metadata_class_equal (g1->container_class, g2->container_class, signature_only))
return FALSE;
for (i = 0; i < g1->inst->type_argc; ++i) {
if (!do_mono_metadata_type_equal (g1->inst->type_argv [i], g2->inst->type_argv [i], signature_only))
* token.
*/
MonoType *
-mono_type_create_from_typespec_full (MonoImage *image, MonoGenericContainer *generic_container, guint32 type_spec)
+mono_type_create_from_typespec_full (MonoImage *image, MonoGenericContext *generic_context, guint32 type_spec)
{
guint32 idx = mono_metadata_token_index (type_spec);
MonoTableInfo *t;
ptr++;
}
- do_mono_metadata_parse_type (type, image, generic_container, ptr, &ptr);
+ do_mono_metadata_parse_type (type, image, generic_context, ptr, &ptr);
mono_loader_unlock ();
}
MonoGenericContainer *
-mono_metadata_load_generic_params (MonoImage *image, guint32 token)
+mono_metadata_load_generic_params (MonoImage *image, guint32 token, MonoGenericContainer *parent_container)
{
MonoTableInfo *tdef = &image->tables [MONO_TABLE_GENERICPARAM];
guint32 cols [MONO_GENERICPARAM_SIZE];
guint32 i, owner = 0, last_num, n;
MonoGenericContainer *container;
+ MonoGenericClass *gclass;
MonoGenericParam *params;
if (mono_metadata_token_table (token) == MONO_TABLE_TYPEDEF)
if (cols [MONO_GENERICPARAM_OWNER] == owner)
break;
}
- last_num = 0;
+ last_num = i;
if (i >= tdef->rows)
return NULL;
params = NULL;
container->type_argc = n;
container->type_params = params;
+ container->parent = parent_container;
+
+ if (mono_metadata_token_table (token) == MONO_TABLE_METHOD)
+ container->is_method = 1;
- container->context = g_new0 (MonoGenericContext, 1);
- container->context->container = container;
+ container->context.container = container;
for (i = 0; i < n; i++)
- params [i].constraints = get_constraints (image, i + 1, container->context);
+ params [i].constraints = get_constraints (image, last_num + i + 1, &container->context);
return container;
}