X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fclass.c;h=6b8d75728face562a7abdf015799acb7d0a052bf;hb=88e4fcdd9a3a68aaacccbacd45522bbea4eb5e23;hp=725053af978fa3a22365ef326f6d3f90173163dd;hpb=c26c60fe43ae165a41794ef72fd13fcd239ba362;p=mono.git diff --git a/mono/metadata/class.c b/mono/metadata/class.c index 725053af978..6b8d75728fa 100644 --- a/mono/metadata/class.c +++ b/mono/metadata/class.c @@ -199,29 +199,32 @@ mono_class_is_open_constructed_type (MonoType *t) } 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; @@ -243,7 +246,7 @@ mono_class_inflate_generic_type (MonoType *type, MonoGenericInst *ginst) 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); @@ -256,16 +259,18 @@ mono_class_inflate_generic_type (MonoType *type, MonoGenericInst *ginst) 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; @@ -274,7 +279,7 @@ mono_class_inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig } static MonoMethodHeader* -inflate_generic_header (MonoMethodHeader *header, MonoGenericInst *ginst) +inflate_generic_header (MonoMethodHeader *header, MonoGenericMethod *gmethod) { MonoMethodHeader *res; int i; @@ -287,15 +292,16 @@ inflate_generic_header (MonoMethodHeader *header, MonoGenericInst *ginst) 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)) { @@ -307,11 +313,11 @@ mono_class_inflate_generic_method (MonoMethod *method, MonoGenericInst *ginst) *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; } @@ -392,7 +398,7 @@ class_compute_field_layout (MonoClass *class) 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]; } @@ -1670,7 +1676,7 @@ get_instantiation_name (const char *name, MonoGenericInst *ginst) 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; @@ -1681,7 +1687,12 @@ mono_class_initialize_generic (MonoGenericInst *ginst, gboolean inflate_methods) 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) { @@ -1690,20 +1701,26 @@ mono_class_initialize_generic (MonoGenericInst *ginst, gboolean 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); @@ -1715,37 +1732,16 @@ mono_class_from_generic (MonoType *gtype, gboolean inflate_methods) 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; @@ -1773,8 +1769,6 @@ mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *image, gb 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++) @@ -1786,7 +1780,7 @@ mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *image, gb 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; @@ -1812,7 +1806,7 @@ my_mono_class_from_generic_parameter (MonoGenericParam *param, gboolean is_mvar) 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; @@ -1958,7 +1952,7 @@ mono_class_from_mono_type (MonoType *type) 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: @@ -1994,7 +1988,7 @@ mono_class_create_from_typespec (MonoImage *image, guint32 type_spec) 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 */