gboolean mono_print_vtable = FALSE;
+/* Function supplied by the runtime to find classes by name using information from the AOT file */
+static MonoGetClassFromName get_class_from_name = NULL;
+
static MonoClass * mono_class_create_from_typedef (MonoImage *image, guint32 type_token);
static void mono_class_create_generic (MonoInflatedGenericClass *gclass);
static gboolean mono_class_get_cached_class_info (MonoClass *klass, MonoCachedClassInfo *res);
/* a typedef in disguise */
return mono_class_from_name (image, nspace, name);
case MONO_RESOLTION_SCOPE_MODULEREF:
- return mono_class_from_name (image->modules [idx - 1], nspace, name);
+ if (image->modules [idx-1])
+ return mono_class_from_name (image->modules [idx - 1], nspace, name);
+ else {
+ char *msg = g_strdup_printf ("%s%s%s", nspace, nspace [0] ? "." : "", name);
+ char *human_name;
+
+ human_name = mono_stringify_assembly_name (&image->assembly->aname);
+ mono_loader_set_error_type_load (msg, human_name);
+ g_free (msg);
+ g_free (human_name);
+
+ return NULL;
+ }
case MONO_RESOLTION_SCOPE_TYPEREF: {
MonoClass *enclosing = mono_class_from_typeref (image, MONO_TOKEN_TYPE_REF | idx);
GList *tmp;
/* If this assert fails, it probably means that you haven't installed an assembly load/search hook */
g_assert (references == image->references);
g_assert (references [idx - 1]);
- if (references [idx - 1] == (gpointer)-1)
+
+ /* If the assembly did not load, register this as a type load exception */
+ if (references [idx - 1] == REFERENCE_MISSING){
+ MonoAssemblyName aname;
+ char *human_name;
+
+ mono_assembly_get_assemblyref (image, idx - 1, &aname);
+ human_name = mono_stringify_assembly_name (&aname);
+ mono_loader_set_error_assembly_load (human_name, image->assembly->ref_only);
+ g_free (human_name);
+
return NULL;
+ }
return mono_class_from_name (references [idx - 1]->image, nspace, name);
}
mono_type_get_name_recurse (
&type->data.array->eklass->byval_arg, str, FALSE, nested_format);
g_string_append_c (str, '[');
+ if (rank == 1)
+ g_string_append_c (str, '*');
for (i = 1; i < rank; i++)
g_string_append_c (str, ',');
g_string_append_c (str, ']');
{
MonoImage *m = class->image;
const int top = class->field.count;
- MonoTableInfo *t = &m->tables [MONO_TABLE_FIELD];
int i;
g_assert (class->enumtype);
MonoGenericContainer *container = NULL;
MonoType *ftype;
- mono_metadata_decode_row (t, idx, cols, MONO_FIELD_SIZE);
+ mono_metadata_decode_table_row (m, MONO_TABLE_FIELD, idx, cols, MONO_FIELD_SIZE);
sig = mono_metadata_blob_heap (m, cols [MONO_FIELD_SIGNATURE]);
mono_metadata_decode_value (sig, &sig);
/* FIELD signature == 0x06 */
MonoImage *m = class->image;
int top = class->field.count;
guint32 layout = class->flags & TYPE_ATTRIBUTE_LAYOUT_MASK;
- MonoTableInfo *t = &m->tables [MONO_TABLE_FIELD];
int i, blittable = TRUE;
guint32 real_size = 0;
guint32 packing_size = 0;
}
class->instance_size = 0;
- class->class_size = 0;
+ if (!class->rank)
+ class->sizes.class_size = 0;
if (class->parent) {
+ /* For generic instances, class->parent might not have been initialized */
+ mono_class_init (class->parent);
if (!class->parent->size_inited)
mono_class_setup_fields (class->parent);
class->instance_size += class->parent->instance_size;
const char *sig;
guint32 cols [MONO_FIELD_SIZE];
- mono_metadata_decode_row (t, idx, cols, MONO_FIELD_SIZE);
+ mono_metadata_decode_table_row (m, MONO_TABLE_FIELD, idx, cols, MONO_FIELD_SIZE);
/* The name is needed for fieldrefs */
field->name = mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]);
sig = mono_metadata_blob_heap (m, cols [MONO_FIELD_SIGNATURE]);
field->type = mono_metadata_parse_type_full (m, container, MONO_PARSE_FIELD, cols [MONO_FIELD_FLAGS], sig + 1, &sig);
if (!field->type) {
mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL);
- continue;
+ break;
}
if (mono_field_is_deleted (field))
continue;
class->instance_size = MAX (real_size, class->instance_size);
}
+ if (class->exception_type)
+ return;
mono_class_layout_fields (class);
}
break;
}
+ if (layout != TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) {
+ /*
+ * For small structs, set min_align to at least the struct size, since the
+ * JIT memset/memcpy code assumes this and generates unaligned accesses
+ * otherwise. See #78990 for a testcase.
+ */
+ if (class->instance_size <= sizeof (MonoObject) + sizeof (gpointer))
+ class->min_align = MAX (class->min_align, class->instance_size - sizeof (MonoObject));
+ }
+
class->size_inited = 1;
/*
continue;
size = mono_type_size (field->type, &align);
- field->offset = class->class_size;
+ field->offset = class->sizes.class_size;
field->offset += align - 1;
field->offset &= ~(align - 1);
- class->class_size = field->offset + size;
+ class->sizes.class_size = field->offset + size;
}
}
{
guint startm, endm, i, j;
guint32 cols [MONO_PROPERTY_SIZE];
- MonoTableInfo *pt = &class->image->tables [MONO_TABLE_PROPERTY];
MonoTableInfo *msemt = &class->image->tables [MONO_TABLE_METHODSEMANTICS];
MonoProperty *properties;
guint32 last;
properties = mono_mempool_alloc0 (class->image->mempool, sizeof (MonoProperty) * class->property.count);
for (i = class->property.first; i < last; ++i) {
- mono_metadata_decode_row (pt, i, cols, MONO_PROPERTY_SIZE);
+ mono_metadata_decode_table_row (class->image, MONO_TABLE_PROPERTY, i, cols, MONO_PROPERTY_SIZE);
properties [i - class->property.first].parent = class;
properties [i - class->property.first].attrs = cols [MONO_PROPERTY_FLAGS];
properties [i - class->property.first].name = mono_metadata_string_heap (class->image, cols [MONO_PROPERTY_NAME]);
{
guint startm, endm, i, j;
guint32 cols [MONO_EVENT_SIZE];
- MonoTableInfo *pt = &class->image->tables [MONO_TABLE_EVENT];
MonoTableInfo *msemt = &class->image->tables [MONO_TABLE_METHODSEMANTICS];
guint32 last;
MonoEvent *events;
events = mono_mempool_alloc0 (class->image->mempool, sizeof (MonoEvent) * class->event.count);
for (i = class->event.first; i < last; ++i) {
MonoEvent *event = &events [i - class->event.first];
-
- mono_metadata_decode_row (pt, i, cols, MONO_EVENT_SIZE);
+
+ mono_metadata_decode_table_row (class->image, MONO_TABLE_EVENT, i, cols, MONO_EVENT_SIZE);
event->parent = class;
event->attrs = cols [MONO_EVENT_FLAGS];
event->name = mono_metadata_string_heap (class->image, cols [MONO_EVENT_NAME]);
MonoGenericContext *context;
guint32 type_token;
int onum = 0;
+ gboolean ok = TRUE;
if (class->vtable)
return;
return;
}
+ mono_stats.generic_vtable_count ++;
+
if (class->generic_class) {
context = class->generic_class->context;
type_token = class->generic_class->container_class->type_token;
if (class->image->dynamic)
mono_reflection_get_dynamic_overrides (class, &overrides, &onum);
- else
- mono_class_get_overrides_full (class->image, type_token, &overrides, &onum, context);
+ else {
+ /* The following call fails if there are missing methods in the type */
+ ok = mono_class_get_overrides_full (class->image, type_token, &overrides, &onum, context);
+ }
- mono_class_setup_vtable_general (class, overrides, onum);
+ if (ok)
+ mono_class_setup_vtable_general (class, overrides, onum);
+
g_free (overrides);
mono_loader_unlock ();
+
+ return;
}
/*
*/
if (!(vtable [io + l])) {
MonoClass *parent = class->parent;
-
- if ((ic->interface_id <= parent->max_interface_id) &&
- (parent->interface_offsets [ic->interface_id] != -1) &&
- parent->vtable)
- vtable [io + l] = parent->vtable [parent->interface_offsets [ic->interface_id] + l];
+
+ for (; parent; parent = parent->parent) {
+ if ((ic->interface_id <= parent->max_interface_id) &&
+ (parent->interface_offsets [ic->interface_id] != -1) &&
+ parent->vtable) {
+ vtable [io + l] = parent->vtable [parent->interface_offsets [ic->interface_id] + l];
+ }
+ }
}
if (!(vtable [io + l])) {
int j;
for (j = 0; j < k->method.count; ++j) {
MonoMethod *m1 = k->methods [j];
+ MonoMethodSignature *cmsig, *m1sig;
+
if (!(m1->flags & METHOD_ATTRIBUTE_VIRTUAL))
continue;
+
+ cmsig = mono_method_signature (cm);
+ m1sig = mono_method_signature (m1);
+
+ if (!cmsig || !m1sig) {
+ mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ return;
+ }
+
if (!strcmp(cm->name, m1->name) &&
- mono_metadata_signature_equal (mono_method_signature (cm), mono_method_signature (m1))) {
+ mono_metadata_signature_equal (cmsig, m1sig)) {
/* CAS - SecurityAction.InheritanceDemand */
if (security_enabled && (m1->flags & METHOD_ATTRIBUTE_HAS_SECURITY)) {
} else
class->vtable_size = cur_slot;
- class->vtable = mono_mempool_alloc0 (class->image->mempool, sizeof (gpointer) * class->vtable_size);
- memcpy (class->vtable, vtable, sizeof (gpointer) * class->vtable_size);
+ /* Try to share the vtable with our parent. */
+ if (class->parent && (class->parent->vtable_size == class->vtable_size) && (memcmp (class->parent->vtable, vtable, sizeof (gpointer) * class->vtable_size) == 0)) {
+ class->vtable = class->parent->vtable;
+ } else {
+ class->vtable = mono_mempool_alloc0 (class->image->mempool, sizeof (gpointer) * class->vtable_size);
+ memcpy (class->vtable, vtable, sizeof (gpointer) * class->vtable_size);
+ }
if (mono_print_vtable) {
int icount = 0;
return n;
}
+static void
+setup_generic_array_ifaces (MonoClass *class, MonoClass *iface, int pos)
+{
+ MonoGenericContext *context;
+ int i;
+
+ context = g_new0 (MonoGenericContext, 1);
+ context->container = iface->generic_class->context->container;
+ context->gmethod = g_new0 (MonoGenericMethod, 1);
+ context->gmethod->generic_class = iface->generic_class;
+ context->gmethod->inst = iface->generic_class->inst;
+
+ for (i = 0; i < class->parent->method.count; i++) {
+ MonoMethod *m = class->parent->methods [i];
+ MonoMethod *inflated;
+ const char *mname, *iname;
+ gchar *name;
+
+ if (!strncmp (m->name, "InternalArray__ICollection_", 27)) {
+ iname = "System.Collections.Generic.ICollection`1.";
+ mname = m->name + 27;
+ } else if (!strncmp (m->name, "InternalArray__IEnumerable_", 27)) {
+ iname = "System.Collections.Generic.IEnumerable`1.";
+ mname = m->name + 27;
+ } else if (!strncmp (m->name, "InternalArray__", 15)) {
+ iname = "System.Collections.Generic.IList`1.";
+ mname = m->name + 15;
+ } else {
+ continue;
+ }
+
+ name = mono_mempool_alloc (class->image->mempool, strlen (iname) + strlen (mname) + 1);
+ strcpy (name, iname);
+ strcpy (name + strlen (iname), mname);
+
+ inflated = mono_class_inflate_generic_method (m, context);
+ class->methods [pos++] = mono_marshal_get_generic_array_helper (class, iface, name, inflated);
+ }
+}
+
/**
* mono_class_init:
* @class: the class to initialize
* compute the instance_size, class_size and other infos that cannot be
* computed at mono_class_get() time. Also compute a generic vtable and
* the method slot numbers. We use this infos later to create a domain
- * specific vtable.
+ * specific vtable.
+ *
+ * Returns TRUE on success or FALSE if there was a problem in loading
+ * the type (incorrect assemblies, missing assemblies, methods, etc).
*/
-void
+gboolean
mono_class_init (MonoClass *class)
{
int i;
MonoCachedClassInfo cached_info;
gboolean has_cached_info;
-
+ int class_init_ok = TRUE;
+
g_assert (class);
if (class->inited)
- return;
+ return TRUE;
/*g_print ("Init class %s\n", class->name);*/
if (class->inited) {
mono_loader_unlock ();
/* Somebody might have gotten in before us */
- return;
+ return TRUE;
}
if (class->init_pending) {
*/
if (has_cached_info) {
class->instance_size = cached_info.instance_size;
- class->class_size = cached_info.class_size;
+ class->sizes.class_size = cached_info.class_size;
class->packing_size = cached_info.packing_size;
class->min_align = cached_info.min_align;
class->blittable = cached_info.blittable;
class->has_references = cached_info.has_references;
class->has_static_refs = cached_info.has_static_refs;
+ class->no_special_static_fields = cached_info.no_special_static_fields;
}
else
- if (!class->size_inited)
+ if (!class->size_inited){
mono_class_setup_fields (class);
+ if (class->exception_type || mono_loader_get_last_error ()){
+ class_init_ok = FALSE;
+ goto leave;
+ }
+ }
+
/* initialize method pointers */
if (class->rank) {
MonoMethod *ctor;
MonoMethodSignature *sig;
- class->method.count = class->rank > 1? 2: 1;
+ int count_generic = 0, first_generic = 0;
+
+ class->method.count = (class->rank > 1? 2: 1);
+
+ if (class->interface_count) {
+ for (i = 0; i < class->parent->method.count; i++) {
+ MonoMethod *m = class->parent->methods [i];
+ if (!strncmp (m->name, "InternalArray__", 15))
+ count_generic++;
+ }
+ first_generic = class->method.count;
+ class->method.count += class->interface_count * count_generic;
+ }
+
sig = mono_metadata_signature_alloc (class->image, class->rank);
sig->ret = &mono_defaults.void_class->byval_arg;
sig->pinvoke = TRUE;
ctor->slot = -1;
class->methods [1] = ctor;
}
+
+ for (i = 0; i < class->interface_count; i++)
+ setup_generic_array_ifaces (class, class->interfaces [i], first_generic + i * count_generic);
}
mono_class_setup_supertypes (class);
}
else {
mono_class_setup_vtable (class);
-
+
+ if (class->exception_type || mono_loader_get_last_error ()){
+ class_init_ok = FALSE;
+ goto leave;
+ }
+
class->ghcimpl = 1;
if (class->parent) {
MonoMethod *cmethod = class->vtable [ghc_slot];
setup_interface_offsets (class, 0);
}
+ leave:
class->inited = 1;
class->init_pending = 0;
-
+
mono_loader_unlock ();
if (mono_debugger_class_init_func)
mono_debugger_class_init_func (class);
+
+ return class_init_ok;
}
/*
}
if (!MONO_CLASS_IS_INTERFACE (class)) {
+ /* Imported COM Objects always derive from __ComObject. */
+ if (MONO_CLASS_IS_IMPORT (class)) {
+ if (parent == mono_defaults.object_class)
+ parent = mono_defaults.com_object_class;
+ }
class->parent = parent;
+
if (!parent)
g_assert_not_reached (); /* FIXME */
class->marshalbyref = parent->marshalbyref;
class->contextbound = parent->contextbound;
class->delegate = parent->delegate;
+ if (MONO_CLASS_IS_IMPORT (class))
+ class->is_com_object = 1;
+ else
+ class->is_com_object = parent->is_com_object;
if (system_namespace) {
if (*class->name == 'M' && !strcmp (class->name, "MarshalByRefObject"))
if (cols [MONO_TYPEDEF_EXTENDS]) {
parent = mono_class_get_full (
image, mono_metadata_token_from_dor (cols [MONO_TYPEDEF_EXTENDS]), context);
+ if (parent == NULL){
+ g_hash_table_remove (image->class_cache, GUINT_TO_POINTER (type_token));
+ mono_loader_unlock ();
+ return NULL;
+ }
}
/* do this early so it's available for interfaces in setup_mono_type () */
mono_class_setup_mono_type (class);
if (!class->enumtype) {
- mono_metadata_interfaces_from_typedef_full (image, type_token, &interfaces, &icount, context);
+ if (!mono_metadata_interfaces_from_typedef_full (
+ image, type_token, &interfaces, &icount, context)){
+ mono_loader_unlock ();
+ return NULL;
+ }
class->interfaces = interfaces;
class->interface_count = icount;
if (gclass->generic_class.is_dynamic) {
klass->instance_size = gklass->instance_size;
- klass->class_size = gklass->class_size;
+ klass->sizes.class_size = gklass->sizes.class_size;
klass->size_inited = 1;
klass->inited = 1;
/**
* @image: context where the image is created
* @type_spec: typespec token
+ * @context: the generic context used to evaluate generic instantiations in
*/
static MonoClass *
-mono_class_create_from_typespec (MonoImage *image, guint32 type_spec)
+mono_class_create_from_typespec (MonoImage *image, guint32 type_spec, MonoGenericContext *context)
{
- return mono_class_from_mono_type (mono_type_create_from_typespec (image, type_spec));
+ MonoType *t = mono_type_create_from_typespec (image, type_spec);
+ if (!t)
+ return NULL;
+ if (context && (context->gclass || context->gmethod)) {
+ MonoType *inflated = inflate_generic_type (t, context);
+ if (inflated)
+ t = inflated;
+ }
+ return mono_class_from_mono_type (t);
}
/**
if ((rootlist = list = g_hash_table_lookup (image->array_cache, eclass))) {
for (; list; list = list->next) {
class = list->data;
- if ((class->rank == rank) && (class->byval_arg.type == (bounded ? MONO_TYPE_ARRAY : MONO_TYPE_SZARRAY))) {
+ if ((class->rank == rank) && (class->byval_arg.type == (((rank > 1) || bounded) ? MONO_TYPE_ARRAY : MONO_TYPE_SZARRAY))) {
mono_loader_unlock ();
return class;
}
if (image->assembly && image->assembly->dynamic && image->assembly_name && strcmp (image->assembly_name, "mscorlib") == 0) {
parent = mono_class_from_name (image, "System", "Array");
corlib_type = TRUE;
- } else if (mono_defaults.generic_array_class) {
- MonoType *inflated, **args;
-
- args = g_new0 (MonoType *, 1);
- args [0] = &eclass->byval_arg;
-
- inflated = mono_class_bind_generic_parameters (
- &mono_defaults.generic_array_class->byval_arg, 1, args);
- parent = mono_class_from_mono_type (inflated);
-
- if (!parent->inited)
- mono_class_init (parent);
} else {
parent = mono_defaults.array_class;
if (!parent->inited)
(eclass->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK);
class->parent = parent;
class->instance_size = mono_class_instance_size (class->parent);
- class->class_size = 0;
+ class->sizes.element_size = mono_class_array_element_size (eclass);
mono_class_setup_supertypes (class);
+
+ if (mono_defaults.generic_ilist_class) {
+ MonoClass *fclass = NULL;
+ int i;
+
+ if (eclass->valuetype) {
+ if (eclass == mono_defaults.int16_class)
+ fclass = mono_defaults.uint16_class;
+ if (eclass == mono_defaults.uint16_class)
+ fclass = mono_defaults.int16_class;
+ if (eclass == mono_defaults.int32_class)
+ fclass = mono_defaults.uint32_class;
+ if (eclass == mono_defaults.uint32_class)
+ fclass = mono_defaults.int32_class;
+ if (eclass == mono_defaults.int64_class)
+ fclass = mono_defaults.uint64_class;
+ if (eclass == mono_defaults.uint64_class)
+ fclass = mono_defaults.int64_class;
+ if (eclass == mono_defaults.byte_class)
+ fclass = mono_defaults.sbyte_class;
+ if (eclass == mono_defaults.sbyte_class)
+ fclass = mono_defaults.byte_class;
+
+ class->interface_count = fclass ? 2 : 1;
+ } else if (MONO_CLASS_IS_INTERFACE (eclass)) {
+ class->interface_count = 2 + eclass->interface_count;
+ } else {
+ class->interface_count = eclass->idepth + eclass->interface_count;
+ }
+
+ class->interfaces = g_new0 (MonoClass *, class->interface_count);
+
+ for (i = 0; i < class->interface_count; i++) {
+ MonoType *inflated, **args;
+ MonoClass *iface;
+
+ if (eclass->valuetype)
+ iface = (i == 0) ? eclass : fclass;
+ else if (MONO_CLASS_IS_INTERFACE (eclass)) {
+ if (i == 0)
+ iface = mono_defaults.object_class;
+ else if (i == 1)
+ iface = eclass;
+ else
+ iface = eclass->interfaces [i - 2];
+ } else {
+ if (i < eclass->idepth)
+ iface = eclass->supertypes [i];
+ else
+ iface = eclass->interfaces [i - eclass->idepth];
+ }
+
+ args = g_new0 (MonoType *, 1);
+ args [0] = &iface->byval_arg;
+
+ inflated = mono_class_bind_generic_parameters (
+ &mono_defaults.generic_ilist_class->byval_arg, 1, args);
+
+ class->interfaces [i] = mono_class_from_mono_type (inflated);
+ }
+ }
+
if (eclass->generic_class)
mono_class_init (eclass);
if (!eclass->size_inited)
if (!klass->inited)
mono_class_init (klass);
- return klass->class_size;
+ /* in arrays, sizes.class_size is unioned with element_size
+ * and arrays have no static fields
+ */
+ if (klass->rank)
+ return 0;
+ return klass->sizes.class_size;
}
/*
}
/**
- * mono_class_get:
+ * mono_class_get_full:
* @image: the image where the class resides
* @type_token: the token for the class
+ * @context: the generic context used to evaluate generic instantiations in
*
* Returns: the MonoClass that represents @type_token in @image
*/
MonoClass *
-mono_class_get (MonoImage *image, guint32 type_token)
+mono_class_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *context)
{
MonoClass *class = NULL;
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, context);
break;
default:
g_warning ("unknown token type %x", type_token & 0xff000000);
}
MonoClass *
-mono_class_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *context)
+mono_class_get (MonoImage *image, guint32 type_token)
{
- MonoClass *class = mono_class_get (image, type_token);
+ return mono_class_get_full (image, type_token, NULL);
+}
- if (!image->dynamic && ((type_token & 0xff000000) == MONO_TOKEN_TYPE_DEF))
- return class;
+/**
+ * mono_image_init_name_cache:
+ *
+ * Initializes the class name cache stored in image->name_cache.
+ *
+ * LOCKING: Acquires the loader lock.
+ */
+void
+mono_image_init_name_cache (MonoImage *image)
+{
+ MonoTableInfo *t = &image->tables [MONO_TABLE_TYPEDEF];
+ guint32 cols [MONO_TYPEDEF_SIZE];
+ const char *name;
+ const char *nspace;
+ guint32 i, visib, nspace_index;
+ GHashTable *name_cache2, *nspace_table;
- if (class && context && (context->gclass || context->gmethod)) {
- MonoType *inflated = inflate_generic_type (&class->byval_arg, context);
- if (inflated)
- class = mono_class_from_mono_type (inflated);
+ mono_loader_lock ();
+
+ image->name_cache = g_hash_table_new (g_str_hash, g_str_equal);
+
+ if (image->dynamic) {
+ mono_loader_unlock ();
+ return;
}
- return class;
+
+ /* Temporary hash table to avoid lookups in the nspace_table */
+ name_cache2 = g_hash_table_new (NULL, NULL);
+
+ for (i = 1; i <= t->rows; ++i) {
+ mono_metadata_decode_row (t, i - 1, cols, MONO_TYPEDEF_SIZE);
+ /* nested types are accessed from the nesting name */
+ visib = cols [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_VISIBILITY_MASK;
+ if (visib > TYPE_ATTRIBUTE_PUBLIC && visib <= TYPE_ATTRIBUTE_NESTED_ASSEMBLY)
+ continue;
+ name = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAME]);
+ nspace = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAMESPACE]);
+
+ nspace_index = cols [MONO_TYPEDEF_NAMESPACE];
+ nspace_table = g_hash_table_lookup (name_cache2, GUINT_TO_POINTER (nspace_index));
+ if (!nspace_table) {
+ nspace_table = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (image->name_cache, (char*)nspace, nspace_table);
+ g_hash_table_insert (name_cache2, GUINT_TO_POINTER (nspace_index),
+ nspace_table);
+ }
+ g_hash_table_insert (nspace_table, (char *) name, GUINT_TO_POINTER (i));
+ }
+
+ /* Load type names from EXPORTEDTYPES table */
+ {
+ MonoTableInfo *t = &image->tables [MONO_TABLE_EXPORTEDTYPE];
+ guint32 cols [MONO_EXP_TYPE_SIZE];
+ int i;
+
+ for (i = 0; i < t->rows; ++i) {
+ mono_metadata_decode_row (t, i, cols, MONO_EXP_TYPE_SIZE);
+ name = mono_metadata_string_heap (image, cols [MONO_EXP_TYPE_NAME]);
+ nspace = mono_metadata_string_heap (image, cols [MONO_EXP_TYPE_NAMESPACE]);
+
+ nspace_index = cols [MONO_EXP_TYPE_NAMESPACE];
+ nspace_table = g_hash_table_lookup (name_cache2, GUINT_TO_POINTER (nspace_index));
+ if (!nspace_table) {
+ nspace_table = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (image->name_cache, (char*)nspace, nspace_table);
+ g_hash_table_insert (name_cache2, GUINT_TO_POINTER (nspace_index),
+ nspace_table);
+ }
+ g_hash_table_insert (nspace_table, (char *) name, GUINT_TO_POINTER (mono_metadata_make_token (MONO_TABLE_EXPORTEDTYPE, i + 1)));
+ }
+ }
+
+ g_hash_table_destroy (name_cache2);
+
+ mono_loader_unlock ();
+}
+
+void
+mono_image_add_to_name_cache (MonoImage *image, const char *nspace,
+ const char *name, guint32 index)
+{
+ GHashTable *nspace_table;
+ GHashTable *name_cache;
+
+ mono_loader_lock ();
+
+ if (!image->name_cache)
+ mono_image_init_name_cache (image);
+
+ name_cache = image->name_cache;
+ if (!(nspace_table = g_hash_table_lookup (name_cache, nspace))) {
+ nspace_table = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (name_cache, (char *)nspace, (char *)nspace_table);
+ }
+ g_hash_table_insert (nspace_table, (char *) name, GUINT_TO_POINTER (index));
+
+ mono_loader_unlock ();
}
typedef struct {
* 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)
mono_loader_lock ();
+ if (!image->name_cache)
+ mono_image_init_name_cache (image);
+
user_data.key = name_space;
user_data.value = NULL;
g_hash_table_foreach (image->name_cache, find_nocase, &user_data);
*
* 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)
name = buf;
}
+ if (get_class_from_name) {
+ gboolean res = get_class_from_name (image, name_space, name, &class);
+ if (res) {
+ if (nested)
+ return class ? return_nested_in (class, nested) : NULL;
+ else
+ return class;
+ }
+ }
+
mono_loader_lock ();
+ if (!image->name_cache)
+ mono_image_init_name_cache (image);
+
nspace_table = g_hash_table_lookup (image->name_cache, name_space);
if (nspace_table)
gint32
mono_array_element_size (MonoClass *ac)
{
- return mono_class_array_element_size (ac->element_class);
+ g_assert (ac->rank);
+ return ac->sizes.element_size;
}
gpointer
return get_cached_class_info (klass, res);
}
+void
+mono_install_get_class_from_name (MonoGetClassFromName func)
+{
+ get_class_from_name = func;
+}
+
MonoImage*
mono_class_get_image (MonoClass *klass)
{
return &klass->byval_arg;
}
+/**
+ * mono_class_get_type_token
+ * @klass: the MonoClass to act on
+ *
+ * This method returns type token for the class.
+ *
+ * Returns: the type token for the class.
+ */
+guint32
+mono_class_get_type_token (MonoClass *klass)
+{
+ return klass->type_token;
+}
+
/**
* mono_class_get_byref_type:
* @klass: the MonoClass to act on
return field->type->attrs;
}
+/**
+ * mono_field_get_data;
+ * @field: the MonoClassField to act on
+ *
+ * Returns: pointer to the metadata constant value or to the field
+ * data if it has an RVA flag.
+ */
+const char *
+mono_field_get_data (MonoClassField *field)
+{
+ return field->data;
+}
+
/**
* mono_property_get_name:
* @prop: the MonoProperty to act on
}
case MONO_EXCEPTION_TYPE_LOAD:
return mono_exception_from_name (mono_defaults.corlib, "System", "TypeLoadException");
- /* TODO - handle other class related failures */
- default:
+
+ default: {
+ MonoLoaderError *error;
+ MonoException *ex;
+
+ error = mono_loader_get_last_error ();
+ if (error != NULL){
+ ex = mono_loader_error_prepare_exception (error);
+ return ex;
+ }
+
+ /* TODO - handle other class related failures */
return NULL;
}
+ }
}