}
MonoType*
-mono_class_inflate_generic_type (MonoType *type, MonoGenericInst *ginst)
+mono_class_inflate_generic_type (MonoType *type, MonoGenericInst *ginst,
+ MonoGenericMethod *gmethod)
{
switch (type->type) {
case MONO_TYPE_MVAR:
- if (ginst)
- return dup_type (ginst->type_argv [type->data.generic_param->num]);
+ if (gmethod && gmethod->mtype_argv)
+ return dup_type (gmethod->mtype_argv [type->data.generic_param->num]);
else
return type;
- case MONO_TYPE_VAR: {
- MonoType *t = ginst->type_argv [type->data.generic_param->num];
-
- if ((t->type == MONO_TYPE_VAR) || (t->type == MONO_TYPE_MVAR))
+ case MONO_TYPE_VAR:
+ if (ginst) {
+ MonoType *t = ginst->type_argv [type->data.generic_param->num];
+
+ if ((t->type == MONO_TYPE_VAR) || (t->type == MONO_TYPE_MVAR))
+ return type;
+ else
+ return dup_type (t);
+ } else
return type;
- else
- return dup_type (t);
- }
case MONO_TYPE_SZARRAY: {
MonoClass *eclass = type->data.klass;
MonoClass *nclass;
MonoType *nt;
- if (eclass->byval_arg.type == MONO_TYPE_MVAR) {
- nclass = mono_class_from_mono_type (ginst->type_argv [eclass->byval_arg.data.generic_param->num]);
- } else if (eclass->byval_arg.type == MONO_TYPE_VAR) {
+ if ((eclass->byval_arg.type == MONO_TYPE_MVAR) && gmethod) {
+ nclass = mono_class_from_mono_type (gmethod->mtype_argv [eclass->byval_arg.data.generic_param->num]);
+ } else if ((eclass->byval_arg.type == MONO_TYPE_VAR) && ginst) {
nclass = mono_class_from_mono_type (ginst->type_argv [eclass->byval_arg.data.generic_param->num]);
} else {
return type;
for (i = 0; i < oginst->type_argc; i++) {
MonoType *t = oginst->type_argv [i];
- nginst->type_argv [i] = mono_class_inflate_generic_type (t, ginst);
+ nginst->type_argv [i] = mono_class_inflate_generic_type (t, ginst, gmethod);
};
nt = dup_type (type);
return type;
}
-MonoMethodSignature*
-mono_class_inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig, MonoGenericInst *ginst)
+static MonoMethodSignature*
+inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig,
+ MonoGenericMethod *gmethod)
{
MonoMethodSignature *res;
int i;
res = mono_metadata_signature_alloc (image, sig->param_count);
- res->ret = mono_class_inflate_generic_type (sig->ret, ginst);
- for (i = 0; i < sig->param_count; ++i) {
- res->params [i] = mono_class_inflate_generic_type (sig->params [i], ginst);
- }
+ res->ret = mono_class_inflate_generic_type (sig->ret, gmethod->generic_inst, gmethod);
+ for (i = 0; i < sig->param_count; ++i)
+ res->params [i] = mono_class_inflate_generic_type (sig->params [i],
+ gmethod->generic_inst,
+ gmethod);
res->hasthis = sig->hasthis;
res->explicit_this = sig->explicit_this;
res->call_convention = sig->call_convention;
}
static MonoMethodHeader*
-inflate_generic_header (MonoMethodHeader *header, MonoGenericInst *ginst)
+inflate_generic_header (MonoMethodHeader *header, MonoGenericMethod *gmethod)
{
MonoMethodHeader *res;
int i;
res->num_locals = header->num_locals;
res->clauses = header->clauses;
res->gen_params = header->gen_params;
- res->geninst = ginst;
- for (i = 0; i < header->num_locals; ++i) {
- res->locals [i] = mono_class_inflate_generic_type (header->locals [i], ginst);
- }
+ res->gen_method = gmethod;
+ for (i = 0; i < header->num_locals; ++i)
+ res->locals [i] = mono_class_inflate_generic_type (header->locals [i],
+ gmethod->generic_inst,
+ gmethod);
return res;
}
MonoMethod*
-mono_class_inflate_generic_method (MonoMethod *method, MonoGenericInst *ginst)
+mono_class_inflate_generic_method (MonoMethod *method, MonoGenericMethod *gmethod)
{
MonoMethod *result;
if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)) {
*nmethod = *(MonoMethodNormal*)method;
result = (MonoMethod*)nmethod;
if (nmethod->header)
- nmethod->header = inflate_generic_header (nmethod->header, ginst);
+ nmethod->header = inflate_generic_header (nmethod->header, gmethod);
}
- if (ginst->klass)
- result->klass = ginst->klass;
- result->signature = mono_class_inflate_generic_signature (method->klass->image, result->signature, ginst);
+ result->klass = gmethod->klass;
+ result->signature = inflate_generic_signature (
+ method->klass->image, result->signature, gmethod);
return result;
}
if (mono_field_is_deleted (field))
continue;
if (class->generic_inst) {
- field->type = mono_class_inflate_generic_type (field->type, class->generic_inst->data.generic_inst);
+ field->type = mono_class_inflate_generic_type (field->type, class->generic_inst, NULL);
field->type->attrs = cols [MONO_FIELD_FLAGS];
}
static void
mono_class_initialize_generic (MonoGenericInst *ginst, gboolean inflate_methods)
{
- MonoClass *klass, *gklass;
+ MonoClass *klass, *gklass, *pklass;
if (ginst->initialized || ginst->init_pending)
return;
klass = ginst->klass;
klass->name = get_instantiation_name (gklass->name, ginst);
- mono_class_setup_parent (klass, gklass->parent);
+ if (ginst->parent)
+ pklass = mono_class_from_mono_type (ginst->parent);
+ else
+ pklass = gklass->parent;
+
+ mono_class_setup_parent (klass, pklass);
mono_class_setup_mono_type (klass);
if (inflate_methods) {
klass->field = gklass->field;
klass->method = gklass->method;
klass->methods = g_new0 (MonoMethod *, klass->method.count);
- for (i = 0; i < klass->method.count; i++)
- klass->methods [i] = mono_class_inflate_generic_method (gklass->methods [i], ginst);
+
+ for (i = 0; i < klass->method.count; i++) {
+ MonoGenericMethod *gmethod = g_new0 (MonoGenericMethod, 1);
+
+ gmethod->klass = klass;
+ gmethod->generic_method = gklass->methods [i];
+ gmethod->generic_inst = ginst;
+
+ klass->methods [i] = mono_class_inflate_generic_method (
+ gklass->methods [i], gmethod);
+ }
}
- g_hash_table_insert (klass->image->generics_cache, ginst->generic_type, klass);
ginst->initialized = TRUE;
}
MonoClass*
-mono_class_from_generic (MonoType *gtype, gboolean inflate_methods)
+mono_class_from_generic (MonoGenericInst *ginst)
{
- MonoGenericInst *ginst = gtype->data.generic_inst;
- MonoClass *class, *gklass;
- MonoImage *image;
+ MonoClass *class, *gklass, *pklass;
if (ginst->klass) {
mono_class_initialize_generic (ginst, TRUE);
gklass = mono_class_from_mono_type (ginst->generic_type);
mono_class_init (gklass);
- image = gklass->image;
- if ((class = g_hash_table_lookup (image->generics_cache, gtype))) {
- mono_loader_unlock ();
- return class;
- }
-
- class = g_malloc0 (sizeof (MonoClass));
+ class = ginst->klass = g_malloc0 (sizeof (MonoClass));
class->name_space = gklass->name_space;
class->name = get_instantiation_name (gklass->name, ginst);
- class->image = image;
+ class->image = gklass->image;
class->flags = gklass->flags;
- class->generic_inst = gtype;
+ class->generic_inst = ginst;
class->cast_class = class->element_class = class;
- if (inflate_methods) {
- int i;
-
- mono_class_setup_parent (class, gklass->parent);
- mono_class_setup_mono_type (class);
-
- class->field = gklass->field;
- class->method = gklass->method;
- class->methods = g_new0 (MonoMethod *, class->method.count);
- for (i = 0; i < class->method.count; i++)
- class->methods [i] = mono_class_inflate_generic_method (gklass->methods [i], ginst);
- }
-
- g_hash_table_insert (image->generics_cache, gtype, class);
-
mono_loader_unlock ();
return class;
klass->parent = mono_defaults.object_class;
if (count - pos > 0) {
- int j;
-
klass->interface_count = count - pos;
klass->interfaces = g_new0 (MonoClass *, count - pos);
for (i = pos; i < count; i++)
klass->image = image;
klass->cast_class = klass->element_class = klass;
klass->enum_basetype = &klass->element_class->byval_arg;
- klass->flags = TYPE_ATTRIBUTE_INTERFACE;
+ klass->flags = TYPE_ATTRIBUTE_INTERFACE | TYPE_ATTRIBUTE_PUBLIC;
klass->this_arg.type = klass->byval_arg.type = is_mvar ? MONO_TYPE_MVAR : MONO_TYPE_VAR;
klass->this_arg.data.generic_param = klass->byval_arg.data.generic_param = param;
klass->image = mono_defaults.corlib;
klass->cast_class = klass->element_class = klass;
klass->enum_basetype = &klass->element_class->byval_arg;
- klass->flags = TYPE_ATTRIBUTE_INTERFACE;
+ klass->flags = TYPE_ATTRIBUTE_INTERFACE | TYPE_ATTRIBUTE_PUBLIC;
klass->this_arg.type = klass->byval_arg.type = is_mvar ? MONO_TYPE_MVAR : MONO_TYPE_VAR;
klass->this_arg.data.generic_param = klass->byval_arg.data.generic_param = param;
case MONO_TYPE_VALUETYPE:
return type->data.klass;
case MONO_TYPE_GENERICINST:
- return mono_class_from_generic (type, TRUE);
+ return mono_class_from_generic (type->data.generic_inst);
case MONO_TYPE_VAR:
return my_mono_class_from_generic_parameter (type->data.generic_param, FALSE);
case MONO_TYPE_MVAR:
class = mono_class_from_mono_type (type->data.type);
break;
case MONO_TYPE_GENERICINST:
- class = mono_class_from_generic (type, TRUE);
+ class = mono_class_from_generic (type->data.generic_inst);
break;
default:
/* it seems any type can be stored in TypeSpec as well */