X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fclass.c;h=cd99a2f1f273d19aceeec46fbcac9451b9e6ff70;hb=55fcbd4b13267a39db7dadd5ae8c055ce83c9f50;hp=fdb27904877319bb01d9eb0da3d7c0c2a33760fc;hpb=c592f59a25c3afe95bb953fbfe6e1501bb0eeeb6;p=mono.git diff --git a/mono/metadata/class.c b/mono/metadata/class.c index fdb27904877..cd99a2f1f27 100644 --- a/mono/metadata/class.c +++ b/mono/metadata/class.c @@ -23,9 +23,10 @@ #include #include #include +#include #include #include -#include +#include #include #include #include @@ -39,6 +40,7 @@ gboolean mono_print_vtable = FALSE; static MonoClass * mono_class_create_from_typedef (MonoImage *image, guint32 type_token); +void (*mono_debugger_start_class_init_func) (MonoClass *klass) = NULL; void (*mono_debugger_class_init_func) (MonoClass *klass) = NULL; MonoClass * @@ -56,16 +58,16 @@ mono_class_from_typeref (MonoImage *image, guint32 type_token) name = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAME]); nspace = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAMESPACE]); - idx = cols [MONO_TYPEREF_SCOPE] >> RESOLTION_SCOPE_BITS; - switch (cols [MONO_TYPEREF_SCOPE] & RESOLTION_SCOPE_MASK) { - case RESOLTION_SCOPE_MODULE: + idx = cols [MONO_TYPEREF_SCOPE] >> MONO_RESOLTION_SCOPE_BITS; + switch (cols [MONO_TYPEREF_SCOPE] & MONO_RESOLTION_SCOPE_MASK) { + case MONO_RESOLTION_SCOPE_MODULE: if (!idx) g_error ("null ResolutionScope not yet handled"); /* a typedef in disguise */ return mono_class_from_name (image, nspace, name); - case RESOLTION_SCOPE_MODULEREF: + case MONO_RESOLTION_SCOPE_MODULEREF: return mono_class_from_name (image->modules [idx - 1], nspace, name); - case RESOLTION_SCOPE_TYPEREF: { + case MONO_RESOLTION_SCOPE_TYPEREF: { MonoClass *enclosing = mono_class_from_typeref (image, MONO_TOKEN_TYPE_REF | idx); GList *tmp; mono_class_init (enclosing); @@ -77,7 +79,7 @@ mono_class_from_typeref (MonoImage *image, guint32 type_token) g_warning ("TypeRef ResolutionScope not yet handled (%d)", idx); return NULL; } - case RESOLTION_SCOPE_ASSEMBLYREF: + case MONO_RESOLTION_SCOPE_ASSEMBLYREF: break; } @@ -86,6 +88,9 @@ mono_class_from_typeref (MonoImage *image, guint32 type_token) /* * detected a reference to mscorlib, we simply return a reference to a dummy * until we have a better solution. + * + * once a better solution is in place, the System.MonoDummy + * class should be removed from CVS. */ fprintf(stderr, "Sending dummy where %s.%s expected\n", mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAMESPACE]), mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAME])); @@ -104,15 +109,19 @@ mono_class_from_typeref (MonoImage *image, guint32 type_token) } static MonoType* -dup_type (MonoType* t) +dup_type (MonoType* t, const MonoType *original) { MonoType *r = g_new0 (MonoType, 1); *r = *t; + r->attrs = original->attrs; + r->byref = original->byref; + mono_stats.generics_metadata_size += sizeof (MonoType); return r; } static void -mono_type_get_name_recurse (MonoType *type, GString *str) +mono_type_get_name_recurse (MonoType *type, GString *str, gboolean is_recursed, + gboolean include_arity) { MonoClass *klass; @@ -120,7 +129,8 @@ mono_type_get_name_recurse (MonoType *type, GString *str) case MONO_TYPE_ARRAY: { int i, rank = type->data.array->rank; - mono_type_get_name_recurse (&type->data.array->eklass->byval_arg, str); + mono_type_get_name_recurse ( + &type->data.array->eklass->byval_arg, str, FALSE, include_arity); g_string_append_c (str, '['); for (i = 1; i < rank; i++) g_string_append_c (str, ','); @@ -128,24 +138,57 @@ mono_type_get_name_recurse (MonoType *type, GString *str) break; } case MONO_TYPE_SZARRAY: - mono_type_get_name_recurse (&type->data.klass->byval_arg, str); + mono_type_get_name_recurse ( + &type->data.klass->byval_arg, str, FALSE, include_arity); g_string_append (str, "[]"); break; case MONO_TYPE_PTR: - mono_type_get_name_recurse (type->data.type, str); + mono_type_get_name_recurse (type->data.type, str, FALSE, include_arity); g_string_append_c (str, '*'); break; default: klass = mono_class_from_mono_type (type); if (klass->nested_in) { - mono_type_get_name_recurse (&klass->nested_in->byval_arg, str); + mono_type_get_name_recurse ( + &klass->nested_in->byval_arg, str, TRUE, include_arity); g_string_append_c (str, '+'); } if (*klass->name_space) { g_string_append (str, klass->name_space); g_string_append_c (str, '.'); } - g_string_append (str, klass->name); + if (!include_arity) { + char *s = strchr (klass->name, '`'); + int len = s ? s - klass->name : strlen (klass->name); + + g_string_append_len (str, klass->name, len); + } else + g_string_append (str, klass->name); + if (is_recursed) + break; + if (klass->generic_inst) { + MonoGenericInst *ginst = klass->generic_inst; + int i; + + g_string_append_c (str, '<'); + for (i = 0; i < ginst->type_argc; i++) { + if (i) + g_string_append_c (str, ','); + mono_type_get_name_recurse ( + ginst->type_argv [i], str, FALSE, include_arity); + } + g_string_append_c (str, '>'); + } else if (klass->gen_params) { + int i; + + g_string_append_c (str, '<'); + for (i = 0; i < klass->num_gen_params; i++) { + if (i) + g_string_append_c (str, ','); + g_string_append (str, klass->gen_params [i].name); + } + g_string_append_c (str, '>'); + } break; } } @@ -157,11 +200,11 @@ mono_type_get_name_recurse (MonoType *type, GString *str) * Returns the string representation for type as required by System.Reflection. * The inverse of mono_reflection_parse_type (). */ -char* -mono_type_get_name (MonoType *type) +static char* +_mono_type_get_name (MonoType *type, gboolean is_recursed, gboolean include_arity) { GString* result = g_string_new (""); - mono_type_get_name_recurse (type, result); + mono_type_get_name_recurse (type, result, is_recursed, include_arity); if (type->byref) g_string_append_c (result, '&'); @@ -169,6 +212,18 @@ mono_type_get_name (MonoType *type) return g_string_free (result, FALSE); } +char* +mono_type_get_name (MonoType *type) +{ + return _mono_type_get_name (type, TRUE, TRUE); +} + +char* +mono_type_get_full_name (MonoType *type) +{ + return _mono_type_get_name (type, FALSE, TRUE); +} + gboolean mono_class_is_open_constructed_type (MonoType *t) { @@ -198,91 +253,126 @@ mono_class_is_open_constructed_type (MonoType *t) } } -MonoType* -mono_class_inflate_generic_type (MonoType *type, MonoGenericInst *ginst, - MonoGenericMethod *gmethod) +static MonoType* +inflate_generic_type (MonoType *type, MonoGenericContext *context) { switch (type->type) { case MONO_TYPE_MVAR: - if (gmethod && gmethod->mtype_argv) - return dup_type (gmethod->mtype_argv [type->data.generic_param->num]); + if (context->gmethod && context->gmethod->mtype_argv) + return dup_type ( + context->gmethod->mtype_argv [type->data.generic_param->num], + type); else - return type; + return NULL; 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; + if (context->ginst) + return dup_type ( + context->ginst->type_argv [type->data.generic_param->num], + type); + else + return NULL; case MONO_TYPE_SZARRAY: { MonoClass *eclass = type->data.klass; - MonoClass *nclass; - MonoType *nt; - 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; - } - nt = dup_type (type); - nt->data.klass = nclass; + MonoType *nt, *inflated = inflate_generic_type (&eclass->byval_arg, context); + if (!inflated) + return NULL; + nt = dup_type (type, type); + nt->data.klass = mono_class_from_mono_type (inflated); return nt; } case MONO_TYPE_GENERICINST: { MonoGenericInst *oginst = type->data.generic_inst; - MonoGenericInst *nginst; + MonoGenericInst *nginst, *cached; MonoType *nt; int i; nginst = g_new0 (MonoGenericInst, 1); *nginst = *oginst; + nginst->is_open = FALSE; + nginst->type_argv = g_new0 (MonoType *, oginst->type_argc); 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, gmethod); + nginst->type_argv [i] = mono_class_inflate_generic_type (t, context); + + if (!nginst->is_open) + nginst->is_open = mono_class_is_open_constructed_type (nginst->type_argv [i]); }; + nginst->klass = NULL; + + nginst->context = g_new0 (MonoGenericContext, 1); + nginst->context->ginst = nginst; + + mono_loader_lock (); + cached = g_hash_table_lookup (oginst->klass->image->generic_inst_cache, nginst); + + if (cached) { + g_free (nginst->type_argv); + g_free (nginst); + mono_loader_unlock (); + + nt = dup_type (type, type); + nt->data.generic_inst = cached; + return nt; + } + + nginst->dynamic_info = NULL; + nginst->initialized = FALSE; + mono_class_create_generic (nginst); - nt = dup_type (type); + mono_stats.generic_instance_count++; + mono_stats.generics_metadata_size += sizeof (MonoGenericInst) + + sizeof (MonoGenericContext) + + nginst->type_argc * sizeof (MonoType); + + nt = dup_type (type, type); nt->data.generic_inst = nginst; + g_hash_table_insert (oginst->klass->image->generic_inst_cache, nginst, nginst); + mono_loader_unlock (); return nt; } default: - return type; + return NULL; } - return type; + return NULL; +} + +MonoType* +mono_class_inflate_generic_type (MonoType *type, MonoGenericContext *context) +{ + MonoType *inflated = inflate_generic_type (type, context); + + if (!inflated) + return type; + + mono_stats.inflated_type_count++; + return inflated; } static MonoMethodSignature* inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig, - MonoGenericMethod *gmethod) + MonoGenericContext *context) { MonoMethodSignature *res; int i; res = mono_metadata_signature_alloc (image, sig->param_count); - res->ret = mono_class_inflate_generic_type (sig->ret, gmethod->generic_inst, gmethod); + res->ret = mono_class_inflate_generic_type (sig->ret, context); for (i = 0; i < sig->param_count; ++i) - res->params [i] = mono_class_inflate_generic_type (sig->params [i], - gmethod->generic_inst, - gmethod); + res->params [i] = mono_class_inflate_generic_type (sig->params [i], context); res->hasthis = sig->hasthis; res->explicit_this = sig->explicit_this; res->call_convention = sig->call_convention; res->generic_param_count = sig->generic_param_count; - res->gen_method = gmethod; + res->is_inflated = 1; return res; } static MonoMethodHeader* -inflate_generic_header (MonoMethodHeader *header, MonoGenericMethod *gmethod) +inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context) { MonoMethodHeader *res; int i; @@ -294,33 +384,58 @@ inflate_generic_header (MonoMethodHeader *header, MonoGenericMethod *gmethod) res->init_locals = header->init_locals; res->num_locals = header->num_locals; res->clauses = header->clauses; - res->gen_params = header->gen_params; for (i = 0; i < header->num_locals; ++i) - res->locals [i] = mono_class_inflate_generic_type (header->locals [i], - gmethod->generic_inst, - gmethod); + res->locals [i] = mono_class_inflate_generic_type (header->locals [i], context); return res; } MonoMethod* -mono_class_inflate_generic_method (MonoMethod *method, MonoGenericMethod *gmethod) +mono_class_inflate_generic_method (MonoMethod *method, MonoGenericContext *context, + MonoClass *klass) { - MonoMethod *result; - if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)) { - MonoMethodPInvoke *nmethod = g_new0 (MonoMethodPInvoke, 1); - *nmethod = *(MonoMethodPInvoke*)method; - result = (MonoMethod*)nmethod; - } else { - MonoMethodNormal *nmethod = g_new0 (MonoMethodNormal, 1); - *nmethod = *(MonoMethodNormal*)method; - result = (MonoMethod*)nmethod; - if (nmethod->header) - nmethod->header = inflate_generic_header (nmethod->header, gmethod); - } - result->klass = gmethod->klass; - result->signature = inflate_generic_signature ( - method->klass->image, result->signature, gmethod); - return result; + MonoMethodInflated *result; + + if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || + (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)) + return method; + + mono_stats.inflated_method_count++; + mono_stats.generics_metadata_size += + sizeof (MonoMethodInflated) - sizeof (MonoMethodNormal); + + result = g_new0 (MonoMethodInflated, 1); + result->nmethod = *(MonoMethodNormal*)method; + + if (result->nmethod.header) + result->nmethod.header = inflate_generic_header ( + result->nmethod.header, context); + + if (klass) + result->nmethod.method.klass = klass; + else { + MonoType *declaring = mono_class_inflate_generic_type ( + &method->klass->byval_arg, context); + result->nmethod.method.klass = mono_class_from_mono_type (declaring); + } + + result->nmethod.method.signature = inflate_generic_signature ( + method->klass->image, method->signature, context); + + if (context->gmethod) { + result->context = g_new0 (MonoGenericContext, 1); + result->context->gmethod = context->gmethod; + result->context->ginst = result->nmethod.method.klass->generic_inst; + + mono_stats.generics_metadata_size += sizeof (MonoGenericContext); + } else + result->context = result->nmethod.method.klass->generic_inst->context; + + if (method->signature->is_inflated) + result->declaring = ((MonoMethodInflated *) method)->declaring; + else + result->declaring = method; + + return (MonoMethod *) result; } /** @@ -354,7 +469,7 @@ class_compute_field_layout (MonoClass *class) class_compute_field_layout (class->parent); class->instance_size += class->parent->instance_size; class->min_align = class->parent->min_align; - blittable = class->blittable; + blittable = class->parent->blittable; } else { class->instance_size = sizeof (MonoObject); class->min_align = 1; @@ -374,9 +489,13 @@ class_compute_field_layout (MonoClass *class) class->instance_size = MAX (real_size, class->instance_size); } class->size_inited = 1; + class->blittable = blittable; return; } + if (layout == TYPE_ATTRIBUTE_AUTO_LAYOUT) + blittable = FALSE; + class->fields = g_new0 (MonoClassField, top); /* @@ -400,14 +519,16 @@ 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, NULL); + field->type = mono_class_inflate_generic_type ( + field->type, class->generic_inst->context); field->type->attrs = cols [MONO_FIELD_FLAGS]; } field->parent = class; - if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) { - if (field->type->byref) { + /* Only do these checks if we still think this type is blittable */ + if (blittable && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) { + if (field->type->byref || MONO_TYPE_IS_REFERENCE (field->type)) { blittable = FALSE; } else { MonoClass *field_class = mono_class_from_mono_type (field->type); @@ -415,9 +536,10 @@ class_compute_field_layout (MonoClass *class) blittable = FALSE; } } + if (layout == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) { mono_metadata_field_info (m, idx, &field->offset, NULL, NULL); - if (field->offset == (guint32)-1) + if (field->offset == (guint32)-1 && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) g_warning ("%s not initialized correctly (missing field layout info for %s)", class->name, field->name); } @@ -425,7 +547,7 @@ class_compute_field_layout (MonoClass *class) mono_metadata_field_info (m, idx, NULL, &rva, NULL); if (!rva) g_warning ("field %s in %s should have RVA data, but hasn't", field->name, class->name); - field->data = mono_cli_rva_map (class->image->image_info, rva); + field->data = mono_image_rva_map (class->image, rva); } if (class->enumtype && !(cols [MONO_FIELD_FLAGS] & FIELD_ATTRIBUTE_STATIC)) { @@ -472,10 +594,13 @@ mono_class_layout_fields (MonoClass *class) * performance. * Requires that all classes whose layout is known to native code be annotated * with [StructLayout (LayoutKind.Sequential)] + * Value types have gc_aware_layout disabled by default, as per + * what the default is for other runtimes. */ /* corlib is missing [StructLayout] directives in many places */ if (layout == TYPE_ATTRIBUTE_AUTO_LAYOUT) { - if (class->image != mono_defaults.corlib) + if (class->image != mono_defaults.corlib && + class->byval_arg.type != MONO_TYPE_VALUETYPE) gc_aware_layout = TRUE; } @@ -596,7 +721,7 @@ mono_class_layout_fields (MonoClass *class) int size, align; field = &class->fields [i]; - if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) + if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC) || field->type->attrs & FIELD_ATTRIBUTE_LITERAL) continue; if (mono_field_is_deleted (field)) continue; @@ -623,6 +748,7 @@ init_properties (MonoClass *class) class->properties = g_new0 (MonoProperty, class->property.count); for (i = class->property.first; i < class->property.last; ++i) { mono_metadata_decode_row (pt, i, cols, MONO_PROPERTY_SIZE); + class->properties [i - class->property.first].parent = class; class->properties [i - class->property.first].attrs = cols [MONO_PROPERTY_FLAGS]; class->properties [i - class->property.first].name = mono_metadata_string_heap (class->image, cols [MONO_PROPERTY_NAME]); @@ -657,6 +783,7 @@ init_events (MonoClass *class) class->events = g_new0 (MonoEvent, class->event.count); for (i = class->event.first; i < class->event.last; ++i) { mono_metadata_decode_row (pt, i, cols, MONO_EVENT_SIZE); + class->events [i - class->event.first].parent = class; class->events [i - class->event.first].attrs = cols [MONO_EVENT_FLAGS]; class->events [i - class->event.first].name = mono_metadata_string_heap (class->image, cols [MONO_EVENT_NAME]); @@ -690,7 +817,7 @@ mono_get_unique_iid (MonoClass *class) char *str; gpointer value; - g_assert (class->flags & TYPE_ATTRIBUTE_INTERFACE); + g_assert (MONO_CLASS_IS_INTERFACE (class)); mono_loader_lock (); @@ -760,7 +887,7 @@ setup_interface_offsets (MonoClass *class, int cur_slot) } } - if (class->flags & TYPE_ATTRIBUTE_INTERFACE) { + if (MONO_CLASS_IS_INTERFACE (class)) { if (max_iid < class->interface_id) max_iid = class->interface_id; } @@ -799,7 +926,7 @@ setup_interface_offsets (MonoClass *class, int cur_slot) } } - if (class->flags & TYPE_ATTRIBUTE_INTERFACE) + if (MONO_CLASS_IS_INTERFACE (class)) class->interface_offsets [class->interface_id] = cur_slot; return cur_slot; @@ -850,7 +977,7 @@ mono_class_setup_vtable (MonoClass *class, MonoMethod **overrides, int onum) /* override interface methods */ for (i = 0; i < onum; i++) { MonoMethod *decl = overrides [i*2]; - if (decl->klass->flags & TYPE_ATTRIBUTE_INTERFACE) { + if (MONO_CLASS_IS_INTERFACE (decl->klass)) { int dslot; g_assert (decl->slot != -1); dslot = decl->slot + class->interface_offsets [decl->klass->interface_id]; @@ -936,15 +1063,24 @@ mono_class_setup_vtable (MonoClass *class, MonoMethod **overrides, int onum) for (l = 0; l < ic->method.count; l++) { MonoMethod *im = ic->methods [l]; - char *qname, *fqname; + char *qname, *fqname, *cname, *the_cname; MonoClass *k1; if (vtable [io + l]) continue; + + if (ic->generic_inst) { + MonoClass *the_ic = mono_class_from_mono_type (ic->generic_inst->generic_type); + the_cname = _mono_type_get_name (&the_ic->byval_arg, TRUE, FALSE); + cname = the_cname; + } else { + the_cname = NULL; + cname = ic->name; + } - qname = g_strconcat (ic->name, ".", im->name, NULL); + qname = g_strconcat (cname, ".", im->name, NULL); if (ic->name_space && ic->name_space [0]) - fqname = g_strconcat (ic->name_space, ".", ic->name, ".", im->name, NULL); + fqname = g_strconcat (ic->name_space, ".", cname, ".", im->name, NULL); else fqname = NULL; @@ -963,6 +1099,7 @@ mono_class_setup_vtable (MonoClass *class, MonoMethod **overrides, int onum) } } } + g_free (the_cname); g_free (qname); g_free (fqname); } @@ -1031,8 +1168,19 @@ mono_class_setup_vtable (MonoClass *class, MonoMethod **overrides, int onum) MonoMethod *cm; cm = class->methods [i]; - - if (!(cm->flags & METHOD_ATTRIBUTE_NEW_SLOT) && (cm->flags & METHOD_ATTRIBUTE_VIRTUAL)) { + + /* + * Non-virtual method have no place in the vtable. + * This also catches static methods (since they are not virtual). + */ + if (!(cm->flags & METHOD_ATTRIBUTE_VIRTUAL)) + continue; + + /* + * If the method is REUSE_SLOT, we must check in the + * base class for a method to override. + */ + if (!(cm->flags & METHOD_ATTRIBUTE_NEW_SLOT)) { int slot = -1; for (k = class->parent; k ; k = k->parent) { int j; @@ -1067,7 +1215,7 @@ mono_class_setup_vtable (MonoClass *class, MonoMethod **overrides, int onum) /* override non interface methods */ for (i = 0; i < onum; i++) { MonoMethod *decl = overrides [i*2]; - if (!(decl->klass->flags & TYPE_ATTRIBUTE_INTERFACE)) { + if (!MONO_CLASS_IS_INTERFACE (decl->klass)) { g_assert (decl->slot != -1); vtable [decl->slot] = overrides [i*2 + 1]; overrides [i * 2 + 1]->slot = decl->slot; @@ -1091,8 +1239,15 @@ mono_class_setup_vtable (MonoClass *class, MonoMethod **overrides, int onum) mono_g_hash_table_destroy (override_map); } - - class->vtable_size = cur_slot; + + if (class->generic_inst) { + MonoClass *gklass = mono_class_from_mono_type (class->generic_inst->generic_type); + + mono_class_init (gklass); + class->vtable_size = gklass->vtable_size; + } else + class->vtable_size = cur_slot; + class->vtable = g_malloc0 (sizeof (gpointer) * class->vtable_size); memcpy (class->vtable, vtable, sizeof (gpointer) * class->vtable_size); @@ -1141,19 +1296,6 @@ mono_class_setup_vtable (MonoClass *class, MonoMethod **overrides, int onum) } } -static MonoMethod * -inflate_method (MonoGenericInst *ginst, MonoMethod *method) -{ - MonoGenericMethod *gmethod = g_new0 (MonoGenericMethod, 1); - - gmethod->klass = ginst->klass; - gmethod->generic_method = method; - gmethod->generic_inst = ginst; - gmethod->declaring = method; - - return mono_class_inflate_generic_method (method, gmethod); -} - /** * mono_class_init: * @class: the class to initialize @@ -1197,11 +1339,15 @@ mono_class_init (MonoClass *class) class->init_pending = 1; + if (mono_debugger_start_class_init_func) + mono_debugger_start_class_init_func (class); + mono_stats.initialized_class_count++; if (class->generic_inst && !class->generic_inst->is_dynamic) { MonoGenericInst *ginst = class->generic_inst; MonoClass *gklass; + GList *list; gklass = mono_class_from_mono_type (ginst->generic_type); mono_class_init (gklass); @@ -1213,21 +1359,28 @@ mono_class_init (MonoClass *class) mono_class_setup_parent (class, class->parent); + if (MONO_CLASS_IS_INTERFACE (class)) + class->interface_id = mono_get_unique_iid (class); + class->method = gklass->method; class->methods = g_new0 (MonoMethod *, class->method.count); for (i = 0; i < class->method.count; i++) - class->methods [i] = inflate_method (ginst, gklass->methods [i]); + class->methods [i] = mono_class_inflate_generic_method ( + gklass->methods [i], ginst->context, ginst->klass); class->field = gklass->field; class->fields = g_new0 (MonoClassField, class->field.count); for (i = 0; i < class->field.count; i++) { + MonoInflatedField *ifield = g_new0 (MonoInflatedField, 1); + ifield->generic_type = gklass->fields [i].type; + class->fields [i] = gklass->fields [i]; - class->fields [i].generic_type = gklass->fields [i].type; + class->fields [i].generic_info = ifield; class->fields [i].parent = class; class->fields [i].type = mono_class_inflate_generic_type ( - class->fields [i].type, ginst, NULL); + class->fields [i].type, ginst->context); } class->property = gklass->property; @@ -1239,10 +1392,28 @@ mono_class_init (MonoClass *class) *prop = gklass->properties [i]; if (prop->get) - prop->get = inflate_method (ginst, prop->get); + prop->get = mono_class_inflate_generic_method ( + prop->get, ginst->context, ginst->klass); if (prop->set) - prop->set = inflate_method (ginst, prop->set); + prop->set = mono_class_inflate_generic_method ( + prop->set, ginst->context, ginst->klass); + + prop->parent = class; + } + + class->interface_count = gklass->interface_count; + class->interfaces = g_new0 (MonoClass *, class->interface_count); + for (i = 0; i < class->interface_count; i++) { + MonoType *it = &gklass->interfaces [i]->byval_arg; + MonoType *inflated = mono_class_inflate_generic_type ( + it, ginst->context); + class->interfaces [i] = mono_class_from_mono_type (inflated); + mono_class_init (class->interfaces [i]); } + + for (list = gklass->nested_classes; list; list = list->next) + class->nested_classes = g_list_append ( + class->nested_classes, list->data); } if (class->parent && !class->parent->inited) @@ -1300,23 +1471,25 @@ mono_class_init (MonoClass *class) } } - init_properties (class); - init_events (class); + if (!class->generic_inst) { + init_properties (class); + init_events (class); - i = mono_metadata_nesting_typedef (class->image, class->type_token, 1); - while (i) { - MonoClass* nclass; - guint32 cols [MONO_NESTED_CLASS_SIZE]; - mono_metadata_decode_row (&class->image->tables [MONO_TABLE_NESTEDCLASS], i - 1, cols, MONO_NESTED_CLASS_SIZE); - nclass = mono_class_create_from_typedef (class->image, MONO_TOKEN_TYPE_DEF | cols [MONO_NESTED_CLASS_NESTED]); - class->nested_classes = g_list_prepend (class->nested_classes, nclass); + i = mono_metadata_nesting_typedef (class->image, class->type_token, 1); + while (i) { + MonoClass* nclass; + guint32 cols [MONO_NESTED_CLASS_SIZE]; + mono_metadata_decode_row (&class->image->tables [MONO_TABLE_NESTEDCLASS], i - 1, cols, MONO_NESTED_CLASS_SIZE); + nclass = mono_class_create_from_typedef (class->image, MONO_TOKEN_TYPE_DEF | cols [MONO_NESTED_CLASS_NESTED]); + class->nested_classes = g_list_prepend (class->nested_classes, nclass); - i = mono_metadata_nesting_typedef (class->image, class->type_token, i + 1); + i = mono_metadata_nesting_typedef (class->image, class->type_token, i + 1); + } } mono_class_setup_supertypes (class); - if (class->flags & TYPE_ATTRIBUTE_INTERFACE) { + if (MONO_CLASS_IS_INTERFACE (class)) { for (i = 0; i < class->method.count; ++i) class->methods [i]->slot = i; class->init_pending = 0; @@ -1327,6 +1500,10 @@ mono_class_init (MonoClass *class) */ setup_interface_offsets (class, 0); mono_loader_unlock (); + + if (mono_debugger_class_init_func) + mono_debugger_class_init_func (class); + return; } @@ -1394,14 +1571,13 @@ mono_class_init (MonoClass *class) mono_debugger_class_init_func (class); } - void mono_class_setup_mono_type (MonoClass *class) { const char *name = class->name; const char *nspace = class->name_space; - if (class->flags & TYPE_ATTRIBUTE_INTERFACE) + if (MONO_CLASS_IS_INTERFACE (class)) class->interface_id = mono_get_unique_iid (class); class->this_arg.byref = 1; @@ -1416,6 +1592,7 @@ mono_class_setup_mono_type (MonoClass *class) * do not set the valuetype bit for System.ValueType. * class->valuetype = 1; */ + class->blittable = TRUE; } else if (!strcmp (name, "Enum")) { /* * do not set the valuetype bit for System.Enum. @@ -1532,7 +1709,7 @@ mono_class_setup_parent (MonoClass *class, MonoClass *parent) return; } - if (!(class->flags & TYPE_ATTRIBUTE_INTERFACE)) { + if (!MONO_CLASS_IS_INTERFACE (class)) { class->parent = parent; if (!parent) @@ -1625,22 +1802,13 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token) } g_assert (mono_metadata_token_table (type_token) == MONO_TABLE_TYPEDEF); - + mono_metadata_decode_row (tt, tidx - 1, cols, MONO_TYPEDEF_SIZE); name = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAME]); nspace = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAMESPACE]); - if (cols [MONO_TYPEDEF_EXTENDS]) - parent = mono_class_get (image, mono_metadata_token_from_dor (cols [MONO_TYPEDEF_EXTENDS])); - interfaces = mono_metadata_interfaces_from_typedef (image, type_token, &icount); - class = g_malloc0 (sizeof (MonoClass)); - - g_hash_table_insert (image->class_cache, GUINT_TO_POINTER (type_token), class); - - class->interfaces = interfaces; - class->interface_count = icount; class->name = name; class->name_space = nspace; @@ -1649,6 +1817,15 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token) class->type_token = type_token; class->flags = cols [MONO_TYPEDEF_FLAGS]; + g_hash_table_insert (image->class_cache, GUINT_TO_POINTER (type_token), class); + + if (cols [MONO_TYPEDEF_EXTENDS]) + parent = mono_class_get (image, mono_metadata_token_from_dor (cols [MONO_TYPEDEF_EXTENDS])); + interfaces = mono_metadata_interfaces_from_typedef (image, type_token, &icount); + + class->interfaces = interfaces; + class->interface_count = icount; + if ((class->flags & TYPE_ATTRIBUTE_STRING_FORMAT_MASK) == TYPE_ATTRIBUTE_UNICODE_CLASS) class->unicode = 1; /* fixme: maybe we must set this on windows @@ -1710,30 +1887,6 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token) return class; } -char* -_mono_class_get_instantiation_name (const char *name, MonoGenericInst *ginst) -{ - GString *res = g_string_new (name); - const char *p; - int i; - MonoClass *argclass; - - p = strchr (name, '<'); - if (p) { - g_string_truncate (res, (p - name) + 1); - } else { - g_string_append_c (res, '<'); - } - for (i = 0; i < ginst->type_argc; ++i) { - if (i > 0) - g_string_append_c (res, ','); - argclass = mono_class_from_mono_type (ginst->type_argv [i]); - g_string_append (res, argclass->name); - } - g_string_append_c (res, '>'); - return g_string_free (res, FALSE); -} - MonoClass* mono_class_create_generic (MonoGenericInst *ginst) { @@ -1745,10 +1898,9 @@ mono_class_create_generic (MonoGenericInst *ginst) gklass = mono_class_from_mono_type (ginst->generic_type); - if (!ginst->init_pending) - klass->name = _mono_class_get_instantiation_name (gklass->name, ginst); - else - klass->name = gklass->name; + klass->nested_in = gklass->nested_in; + + klass->name = gklass->name; klass->name_space = gklass->name_space; klass->image = gklass->image; klass->flags = gklass->flags; @@ -1787,11 +1939,10 @@ mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *image, gb ; pos = 0; - if ((count > 0) && !(param->constraints [0]->flags & TYPE_ATTRIBUTE_INTERFACE)) { + if ((count > 0) && !MONO_CLASS_IS_INTERFACE (param->constraints [0])) { klass->parent = param->constraints [0]; pos++; - } else - klass->parent = mono_defaults.object_class; + } if (count - pos > 0) { klass->interface_count = count - pos; @@ -1800,12 +1951,14 @@ mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *image, gb klass->interfaces [i - pos] = param->constraints [i]; } - klass->name = g_strdup_printf (is_mvar ? "!!%d" : "!%d", param->num); + g_assert (param->name); + + klass->name = param->name; klass->name_space = ""; klass->image = image; klass->cast_class = klass->element_class = klass; klass->enum_basetype = &klass->element_class->byval_arg; - klass->flags = TYPE_ATTRIBUTE_INTERFACE | TYPE_ATTRIBUTE_PUBLIC; + klass->flags = 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; @@ -1826,12 +1979,15 @@ my_mono_class_from_generic_parameter (MonoGenericParam *param, gboolean is_mvar) klass = g_new0 (MonoClass, 1); - klass->name = g_strdup_printf (is_mvar ? "!!%d" : "!%d", param->num); + if (param->name) + klass->name = param->name; + else + klass->name = g_strdup_printf (is_mvar ? "!!%d" : "!%d", param->num); klass->name_space = ""; 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 | TYPE_ATTRIBUTE_PUBLIC; + klass->flags = 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; @@ -1861,8 +2017,8 @@ mono_ptr_class_get (MonoType *type) result = g_new0 (MonoClass, 1); result->parent = NULL; /* no parent for PTR types */ - result->name = "System"; - result->name_space = "MonoPtrFakeClass"; + result->name_space = el_class->name_space; + result->name = g_strdup_printf ("%s*", el_class->name); result->image = el_class->image; result->inited = TRUE; result->flags = TYPE_ATTRIBUTE_CLASS | (el_class->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK); @@ -1870,6 +2026,7 @@ mono_ptr_class_get (MonoType *type) result->instance_size = sizeof (gpointer); result->cast_class = result->element_class = el_class; result->enum_basetype = &result->element_class->byval_arg; + result->blittable = TRUE; result->this_arg.type = result->byval_arg.type = MONO_TYPE_PTR; result->this_arg.data.type = result->byval_arg.data.type = result->enum_basetype; @@ -1906,15 +2063,17 @@ mono_fnptr_class_get (MonoMethodSignature *sig) result->name_space = "MonoFNPtrFakeClass"; result->image = NULL; /* need to fix... */ result->inited = TRUE; - result->flags = TYPE_ATTRIBUTE_CLASS; // | (el_class->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK); + result->flags = TYPE_ATTRIBUTE_CLASS; /* | (el_class->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK); */ /* Can pointers get boxed? */ result->instance_size = sizeof (gpointer); result->cast_class = result->element_class = result; + result->blittable = TRUE; result->this_arg.type = result->byval_arg.type = MONO_TYPE_FNPTR; result->this_arg.data.method = result->byval_arg.data.method = sig; result->this_arg.byref = TRUE; result->enum_basetype = &result->element_class->byval_arg; + result->blittable = TRUE; mono_class_setup_supertypes (result); @@ -1996,9 +2155,10 @@ mono_class_from_mono_type (MonoType *type) * @type_spec: typespec token */ static MonoClass * -mono_class_create_from_typespec (MonoImage *image, guint32 type_spec) +mono_class_create_from_typespec (MonoImage *image, guint32 type_spec, + MonoGenericContext *context) { - MonoType *type; + MonoType *type, *inflated; MonoClass *class; type = mono_type_create_from_typespec (image, type_spec); @@ -2011,11 +2171,11 @@ mono_class_create_from_typespec (MonoImage *image, guint32 type_spec) class = mono_array_class_get (type->data.klass, 1); break; case MONO_TYPE_PTR: - class = mono_class_from_mono_type (type->data.type); + class = mono_ptr_class_get (type->data.type); break; case MONO_TYPE_GENERICINST: g_assert (type->data.generic_inst->klass); - return type->data.generic_inst->klass; + class = type->data.generic_inst->klass; break; default: /* it seems any type can be stored in TypeSpec as well */ @@ -2023,7 +2183,12 @@ mono_class_create_from_typespec (MonoImage *image, guint32 type_spec) break; } - return class; + if (!class || !context) + return class; + + inflated = mono_class_inflate_generic_type (&class->byval_arg, context); + + return mono_class_from_mono_type (inflated); } /** @@ -2272,6 +2437,12 @@ mono_class_get_field_from_name (MonoClass *klass, const char *name) return NULL; } +void * +mono_vtable_get_static_field_data (MonoVTable *vt) +{ + return vt->data; +} + MonoProperty* mono_class_get_property_from_name (MonoClass *klass, const char *name) { @@ -2311,7 +2482,7 @@ mono_class_get (MonoImage *image, guint32 type_token) class = mono_class_from_typeref (image, type_token); break; case MONO_TOKEN_TYPE_SPEC: - class = mono_class_create_from_typespec (image, type_token); + class = mono_class_create_from_typespec (image, type_token, NULL); break; default: g_warning ("unknown token type %x", type_token & 0xff000000); @@ -2324,6 +2495,50 @@ mono_class_get (MonoImage *image, guint32 type_token) return class; } +MonoClass * +mono_class_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *context) +{ + MonoClass *class = mono_class_get (image, type_token); + MonoType *inflated; + + if (!class || !context) + return class; + + switch (class->byval_arg.type) { + case MONO_TYPE_GENERICINST: + if (!class->generic_inst->is_open) + return class; + break; + case MONO_TYPE_VAR: + case MONO_TYPE_MVAR: + break; + default: + return class; + } + + inflated = inflate_generic_type (&class->byval_arg, context); + if (!inflated) + return class; + + return mono_class_from_mono_type (inflated); +} + +/** + * mono_class_from_name_case: + * @image: The MonoImage where the type is looked up in, or NULL for looking up in all loaded assemblies + * @name_space: the type namespace + * @name: the type short name. + * + * Obtains a MonoClass with a given namespace and a given name which + * is located in the given MonoImage. The namespace and name + * lookups are case insensitive. + * + * You can also pass `NULL' to the image, and that will lookup for + * a type with the given namespace and name in all of the loaded + * assemblies: notice that since there might be a name clash in this + * case, passing NULL is not encouraged if you need a precise type. + * + */ MonoClass * mono_class_from_name_case (MonoImage *image, const char* name_space, const char *name) { @@ -2369,6 +2584,22 @@ return_nested_in (MonoClass *class, char *nested) { return NULL; } + +/** + * mono_class_from_name_case: + * @image: The MonoImage where the type is looked up in, or NULL for looking up in all loaded assemblies + * @name_space: the type namespace + * @name: the type short name. + * + * Obtains a MonoClass with a given namespace and a given name which + * is located in the given MonoImage. + * + * You can also pass `NULL' to the image, and that will lookup for + * a type with the given namespace and name in all of the loaded + * assemblies: notice that since there might be a name clash in this + * case, passing NULL is not encouraged if you need a precise type. + * + */ MonoClass * mono_class_from_name (MonoImage *image, const char* name_space, const char *name) { @@ -2412,8 +2643,8 @@ mono_class_from_name (MonoImage *image, const char* name_space, const char *name mono_metadata_decode_row (t, idx - 1, cols, MONO_EXP_TYPE_SIZE); impl = cols [MONO_EXP_TYPE_IMPLEMENTATION]; - if ((impl & IMPLEMENTATION_MASK) == IMPLEMENTATION_FILE) { - loaded_image = mono_assembly_load_module (image->assembly, impl >> IMPLEMENTATION_BITS); + if ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE) { + loaded_image = mono_assembly_load_module (image->assembly, impl >> MONO_IMPLEMENTATION_BITS); if (!loaded_image) return NULL; class = mono_class_from_name (loaded_image, name_space, name); @@ -2438,11 +2669,11 @@ mono_class_is_subclass_of (MonoClass *klass, MonoClass *klassc, gboolean check_interfaces) { again: - if (check_interfaces && (klassc->flags & TYPE_ATTRIBUTE_INTERFACE) && !(klass->flags & TYPE_ATTRIBUTE_INTERFACE)) { + if (check_interfaces && MONO_CLASS_IS_INTERFACE (klassc) && !MONO_CLASS_IS_INTERFACE (klass)) { if ((klassc->interface_id <= klass->max_interface_id) && (klass->interface_offsets [klassc->interface_id] >= 0)) return TRUE; - } else if (check_interfaces && (klassc->flags & TYPE_ATTRIBUTE_INTERFACE) && (klass->flags & TYPE_ATTRIBUTE_INTERFACE)) { + } else if (check_interfaces && MONO_CLASS_IS_INTERFACE (klassc) && MONO_CLASS_IS_INTERFACE (klass)) { int i; for (i = 0; i < klass->interface_count; i ++) { @@ -2451,18 +2682,8 @@ mono_class_is_subclass_of (MonoClass *klass, MonoClass *klassc, return TRUE; } } else { - if (!(klass->flags & TYPE_ATTRIBUTE_INTERFACE) && mono_class_has_parent (klass, klassc)) + if (!MONO_CLASS_IS_INTERFACE (klass) && mono_class_has_parent (klass, klassc)) return TRUE; - if (klass->generic_inst) { - MonoType *parent = klass->generic_inst->parent; - if (!parent) - return FALSE; - - if (mono_metadata_type_equal (parent, &klassc->byval_arg)) - return TRUE; - klass = mono_class_from_mono_type (parent); - goto again; - } } /* @@ -2471,6 +2692,17 @@ mono_class_is_subclass_of (MonoClass *klass, MonoClass *klassc, */ if (klassc == mono_defaults.object_class) return TRUE; + + if (klass->generic_inst) { + MonoType *parent = klass->generic_inst->parent; + if (!parent) + return FALSE; + + if (mono_metadata_type_equal (parent, &klassc->byval_arg)) + return TRUE; + klass = mono_class_from_mono_type (parent); + goto again; + } return FALSE; } @@ -2484,7 +2716,7 @@ mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass) if (!oklass->inited) mono_class_init (oklass); - if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) { + if (MONO_CLASS_IS_INTERFACE (klass)) { if ((klass->interface_id <= oklass->max_interface_id) && (oklass->interface_offsets [klass->interface_id] != -1)) return TRUE; @@ -2555,10 +2787,10 @@ mono_class_needs_cctor_run (MonoClass *klass, MonoMethod *caller) gint32 mono_class_array_element_size (MonoClass *klass) { - int t = klass->byval_arg.type; + MonoType *type = &klass->byval_arg; handle_enum: - switch (t) { + switch (type->type) { case MONO_TYPE_I1: case MONO_TYPE_U1: case MONO_TYPE_BOOLEAN: @@ -2587,13 +2819,16 @@ handle_enum: case MONO_TYPE_R8: return 8; case MONO_TYPE_VALUETYPE: - if (klass->enumtype) { - t = klass->enum_basetype->type; + if (type->data.klass->enumtype) { + type = type->data.klass->enum_basetype; goto handle_enum; } - return mono_class_instance_size (klass) - sizeof (MonoObject); + return mono_class_instance_size (type->data.klass) - sizeof (MonoObject); + case MONO_TYPE_GENERICINST: + type = type->data.generic_inst->generic_type; + goto handle_enum; default: - g_error ("unknown type 0x%02x in mono_class_array_element_size", t); + g_error ("unknown type 0x%02x in mono_class_array_element_size", type->type); } return -1; } @@ -2611,7 +2846,8 @@ mono_array_element_size (MonoClass *ac) } gpointer -mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class) +mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class, + MonoGenericContext *context) { if (image->dynamic) { gpointer obj = mono_lookup_dynamic_token (image, token); @@ -2642,7 +2878,7 @@ mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class) MonoClass *class; if (handle_class) *handle_class = mono_defaults.typehandle_class; - class = mono_class_get (image, token); + class = mono_class_get_full (image, token, context); mono_class_init (class); /* We return a MonoType* as handle */ return &class->byval_arg; @@ -2651,14 +2887,14 @@ mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class) MonoClass *class; if (handle_class) *handle_class = mono_defaults.typehandle_class; - class = mono_class_create_from_typespec (image, token); + class = mono_class_create_from_typespec (image, token, context); mono_class_init (class); return &class->byval_arg; } case MONO_TOKEN_FIELD_DEF: { MonoClass *class; guint32 type = mono_metadata_typedef_from_field (image, mono_metadata_token_index (token)); - class = mono_class_get (image, MONO_TOKEN_TYPE_DEF | type); + class = mono_class_get_full (image, MONO_TOKEN_TYPE_DEF | type, context); mono_class_init (class); if (handle_class) *handle_class = mono_defaults.fieldhandle_class; @@ -2666,7 +2902,7 @@ mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class) } case MONO_TOKEN_METHOD_DEF: { MonoMethod *meth; - meth = mono_get_method (image, token, NULL); + meth = mono_get_method_full (image, token, NULL, context); if (handle_class) *handle_class = mono_defaults.methodhandle_class; return meth; @@ -2680,13 +2916,13 @@ mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class) if (*sig == 0x6) { /* it's a field */ MonoClass *klass; MonoClassField *field; - field = mono_field_from_token (image, token, &klass); + field = mono_field_from_token (image, token, &klass, context); if (handle_class) *handle_class = mono_defaults.fieldhandle_class; return field; } else { MonoMethod *meth; - meth = mono_get_method (image, token, NULL); + meth = mono_get_method_full (image, token, NULL, context); if (handle_class) *handle_class = mono_defaults.methodhandle_class; return meth; @@ -2717,5 +2953,624 @@ mono_lookup_dynamic_token (MonoImage *image, guint32 token) return lookup_dynamic (image, token); } +MonoImage* +mono_class_get_image (MonoClass *klass) +{ + return klass->image; +} + +/** + * mono_class_get_element_class: + * @klass: the MonoClass to act on + * + * Returns the element class of an array or an enumeration. + */ +MonoClass* +mono_class_get_element_class (MonoClass *klass) +{ + return klass->element_class; +} + +/** + * mono_class_is_valuetype: + * @klass: the MonoClass to act on + * + * Returns true if the MonoClass represents a ValueType. + */ +gboolean +mono_class_is_valuetype (MonoClass *klass) +{ + return klass->valuetype; +} + +/** + * mono_class_is_enum: + * @klass: the MonoClass to act on + * + * Returns true if the MonoClass represents an enumeration. + */ +gboolean +mono_class_is_enum (MonoClass *klass) +{ + return klass->enumtype; +} + +/** + * mono_class_enum_basetype: + * @klass: the MonoClass to act on + * + * Returns the underlying type representation for an enumeration. + */ +MonoType* +mono_class_enum_basetype (MonoClass *klass) +{ + return klass->enum_basetype; +} + +/** + * mono_class_get_parent + * @klass: the MonoClass to act on + * + * Returns the parent class for this class. + */ +MonoClass* +mono_class_get_parent (MonoClass *klass) +{ + return klass->parent; +} + +/** + * mono_class_get_nesting_type; + * @klass: the MonoClass to act on + * + * Returns the container type where this type is nested or NULL if this type is not a nested type. + */ +MonoClass* +mono_class_get_nesting_type (MonoClass *klass) +{ + return klass->nested_in; +} + +/** + * mono_class_get_rank: + * @klass: the MonoClass to act on + * + * Returns the rank for the array (the number of dimensions). + */ +int +mono_class_get_rank (MonoClass *klass) +{ + return klass->rank; +} +/** + * mono_class_get_flags: + * @klass: the MonoClass to act on + * + * The type flags from the TypeDef table from the metadata. + * see the TYPE_ATTRIBUTE_* definitions on tabledefs.h for the + * different values. + * + * Returns the flags from the TypeDef table. + */ +guint32 +mono_class_get_flags (MonoClass *klass) +{ + return klass->flags; +} + +/** + * mono_class_get_name + * @klass: the MonoClass to act on + * + * Returns the name of the class. + */ +const char* +mono_class_get_name (MonoClass *klass) +{ + return klass->name; +} + +/** + * mono_class_get_namespace: + * @klass: the MonoClass to act on + * + * Returns the namespace of the class. + */ +const char* +mono_class_get_namespace (MonoClass *klass) +{ + return klass->name_space; +} + +/** + * mono_class_get_type: + * @klass: the MonoClass to act on + * + * This method returns the internal Type representation for the class. + * + * Returns the MonoType from the class. + */ +MonoType* +mono_class_get_type (MonoClass *klass) +{ + return &klass->byval_arg; +} + +/** + * mono_class_get_byref_type: + * @klass: the MonoClass to act on + * + * + */ +MonoType* +mono_class_get_byref_type (MonoClass *klass) +{ + return &klass->this_arg; +} + +/** + * mono_class_num_fields: + * @klass: the MonoClass to act on + * + * Returns the number of static and instance fields in the class. + */ +int +mono_class_num_fields (MonoClass *klass) +{ + return klass->field.count; +} + +/** + * mono_class_num_methods: + * @klass: the MonoClass to act on + * + * Returns the number of methods in the class. + */ +int +mono_class_num_methods (MonoClass *klass) +{ + return klass->method.count; +} + +/** + * mono_class_num_properties + * @klass: the MonoClass to act on + * + * Returns the number of properties in the class. + */ +int +mono_class_num_properties (MonoClass *klass) +{ + return klass->property.count; +} + +/** + * mono_class_num_events: + * @klass: the MonoClass to act on + * + * Returns the number of events in the class. + */ +int +mono_class_num_events (MonoClass *klass) +{ + return klass->event.count; +} + +/** + * mono_class_get_fields: + * @klass: the MonoClass to act on + * + * This routine is an iterator routine for retrieving the fields in a class. + * + * You must pass a gpointer that points to zero and is treated as an opaque handle to + * iterate over all of the elements. When no more values are + * available, the return value is NULL. + * + * Returns a `MonoClassField *' on each iteration, or NULL when no more fields are available. + */ +MonoClassField* +mono_class_get_fields (MonoClass* klass, gpointer *iter) +{ + MonoClassField* field; + if (!iter) + return NULL; + if (!klass->inited) + mono_class_init (klass); + if (!*iter) { + /* start from the first */ + if (klass->field.count) { + return *iter = &klass->fields [0]; + } else { + /* no fields */ + return NULL; + } + } + field = *iter; + field++; + if (field < &klass->fields [klass->field.count]) { + return *iter = field; + } + return NULL; +} + +/** + * mono_class_get_methods + * @klass: the MonoClass to act on + * + * This routine is an iterator routine for retrieving the fields in a class. + * + * You must pass a gpointer that points to zero and is treated as an opaque handle to + * iterate over all of the elements. When no more values are + * available, the return value is NULL. + * + * Returns a MonoMethod on each iteration or NULL when no more methods are available. + */ +MonoMethod* +mono_class_get_methods (MonoClass* klass, gpointer *iter) +{ + MonoMethod** method; + if (!iter) + return NULL; + if (!klass->inited) + mono_class_init (klass); + if (!*iter) { + /* start from the first */ + if (klass->method.count) { + *iter = &klass->methods [0]; + return klass->methods [0]; + } else { + /* no method */ + return NULL; + } + } + method = *iter; + method++; + if (method < &klass->methods [klass->method.count]) { + *iter = method; + return *method; + } + return NULL; +} + +/** + * mono_class_get_properties: + * @klass: the MonoClass to act on + * + * This routine is an iterator routine for retrieving the properties in a class. + * + * You must pass a gpointer that points to zero and is treated as an opaque handle to + * iterate over all of the elements. When no more values are + * available, the return value is NULL. + * + * Returns a `MonoProperty *' on each invocation, or NULL when no more are available. + */ +MonoProperty* +mono_class_get_properties (MonoClass* klass, gpointer *iter) +{ + MonoProperty* property; + if (!iter) + return NULL; + if (!klass->inited) + mono_class_init (klass); + if (!*iter) { + /* start from the first */ + if (klass->property.count) { + return *iter = &klass->properties [0]; + } else { + /* no fields */ + return NULL; + } + } + property = *iter; + property++; + if (property < &klass->properties [klass->property.count]) { + return *iter = property; + } + return NULL; +} + +/** + * mono_class_get_events: + * @klass: the MonoClass to act on + * + * This routine is an iterator routine for retrieving the properties in a class. + * + * You must pass a gpointer that points to zero and is treated as an opaque handle to + * iterate over all of the elements. When no more values are + * available, the return value is NULL. + * + * Returns a `MonoEvent *' on each invocation, or NULL when no more are available. + */ +MonoEvent* +mono_class_get_events (MonoClass* klass, gpointer *iter) +{ + MonoEvent* event; + if (!iter) + return NULL; + if (!klass->inited) + mono_class_init (klass); + if (!*iter) { + /* start from the first */ + if (klass->event.count) { + return *iter = &klass->events [0]; + } else { + /* no fields */ + return NULL; + } + } + event = *iter; + event++; + if (event < &klass->events [klass->event.count]) { + return *iter = event; + } + return NULL; +} + +/** + * mono_class_get_interfaaces + * @klass: the MonoClass to act on + * + * This routine is an iterator routine for retrieving the interfaces implemented by this class. + * + * You must pass a gpointer that points to zero and is treated as an opaque handle to + * iterate over all of the elements. When no more values are + * available, the return value is NULL. + * + * Returns a `Monoclass *' on each invocation, or NULL when no more are available. + */ +MonoClass* +mono_class_get_interfaces (MonoClass* klass, gpointer *iter) +{ + MonoClass** iface; + if (!iter) + return NULL; + if (!klass->inited) + mono_class_init (klass); + if (!*iter) { + /* start from the first */ + if (klass->interface_count) { + *iter = &klass->interfaces [0]; + return klass->interfaces [0]; + } else { + /* no interface */ + return NULL; + } + } + iface = *iter; + iface++; + if (iface < &klass->interfaces [klass->interface_count]) { + *iter = iface; + return *iface; + } + return NULL; +} + +/** + * mono_class_get_interfaaces + * @klass: the MonoClass to act on + * + * This routine is an iterator routine for retrieving the nested types of a class. + * + * You must pass a gpointer that points to zero and is treated as an opaque handle to + * iterate over all of the elements. When no more values are + * available, the return value is NULL. + * + * Returns a `Monoclass *' on each invocation, or NULL when no more are available. + */ +MonoClass* +mono_class_get_nested_types (MonoClass* klass, gpointer *iter) +{ + GList *item; + if (!iter) + return NULL; + if (!klass->inited) + mono_class_init (klass); + if (!*iter) { + /* start from the first */ + if (klass->nested_classes) { + *iter = klass->nested_classes; + return klass->nested_classes->data; + } else { + /* no nested types */ + return NULL; + } + } + item = *iter; + item = item->next; + if (item) { + *iter = item; + return item->data; + } + return NULL; +} + +/** + * mono_field_get_name: + * @field: the MonoClassField to act on + * + * Returns the name of the field. + */ +const char* +mono_field_get_name (MonoClassField *field) +{ + return field->name; +} + +/** + * mono_field_get_type: + * @field: the MonoClassField to act on + * + * Returns MonoType of the field. + */ +MonoType* +mono_field_get_type (MonoClassField *field) +{ + return field->type; +} + +/** + * mono_field_get_type: + * @field: the MonoClassField to act on + * + * Returns MonoClass where the field was defined. + */ +MonoClass* +mono_field_get_parent (MonoClassField *field) +{ + return field->parent; +} + +/** + * mono_field_get_flags; + * @field: the MonoClassField to act on + * + * The metadata flags for a field are encoded using the + * FIELD_ATTRIBUTE_* constants. See the tabledefs.h file for details. + * + * Returns the flags for the field. + */ +guint32 +mono_field_get_flags (MonoClassField *field) +{ + return field->type->attrs; +} + +/** + * mono_property_get_name: + * @prop: the MonoProperty to act on + * + * Returns the name of the property + */ +const char* +mono_property_get_name (MonoProperty *prop) +{ + return prop->name; +} + +/** + * mono_property_get_set_method + * @prop: the MonoProperty to act on. + * + * Returns the setter method of the property (A MonoMethod) + */ +MonoMethod* +mono_property_get_set_method (MonoProperty *prop) +{ + return prop->set; +} + +/** + * mono_property_get_get_method + * @prop: the MonoProperty to act on. + * + * Returns the setter method of the property (A MonoMethod) + */ +MonoMethod* +mono_property_get_get_method (MonoProperty *prop) +{ + return prop->get; +} + +/** + * mono_property_get_parent: + * @prop: the MonoProperty to act on. + * + * Returns the MonoClass where the property was defined. + */ +MonoClass* +mono_property_get_parent (MonoProperty *prop) +{ + return prop->parent; +} + +/** + * mono_property_get_flags: + * @prop: the MonoProperty to act on. + * + * The metadata flags for a property are encoded using the + * PROPERTY_ATTRIBUTE_* constants. See the tabledefs.h file for details. + * + * Returns the flags for the property. + */ +guint32 +mono_property_get_flags (MonoProperty *prop) +{ + return prop->attrs; +} + +/** + * mono_event_get_name: + * @event: the MonoEvent to act on + * + * Returns the name of the event. + */ +const char* +mono_event_get_name (MonoEvent *event) +{ + return event->name; +} + +/** + * mono_event_get_add_method: + * @event: The MonoEvent to act on. + * + * Returns the `add' method for the event (a MonoMethod). + */ +MonoMethod* +mono_event_get_add_method (MonoEvent *event) +{ + return event->add; +} + +/** + * mono_event_get_remove_method: + * @event: The MonoEvent to act on. + * + * Returns the `remove' method for the event (a MonoMethod). + */ +MonoMethod* +mono_event_get_remove_method (MonoEvent *event) +{ + return event->remove; +} + +/** + * mono_event_get_raise_method: + * @event: The MonoEvent to act on. + * + * Returns the `raise' method for the event (a MonoMethod). + */ +MonoMethod* +mono_event_get_raise_method (MonoEvent *event) +{ + return event->raise; +} + +/** + * mono_event_get_parent: + * @event: the MonoEvent to act on. + * + * Returns the MonoClass where the event is defined. + */ +MonoClass* +mono_event_get_parent (MonoEvent *event) +{ + return event->parent; +} + +/** + * mono_event_get_flags + * @event: the MonoEvent to act on. + * + * The metadata flags for an event are encoded using the + * EVENT_* constants. See the tabledefs.h file for details. + * + * Returns the flags for the event. + */ +guint32 +mono_event_get_flags (MonoEvent *event) +{ + return event->attrs; +}