MonoClass *enclosing = mono_class_from_typeref (image, MONO_TOKEN_TYPE_REF | idx);
GList *tmp;
- if (enclosing->inited) {
+ if (enclosing->nested_classes_inited) {
/* Micro-optimization: don't scan the metadata tables if enclosing is already inited */
for (tmp = enclosing->nested_classes; tmp; tmp = tmp->next) {
res = tmp->data;
}
/*
- * This method allows specifying a mempool to do type duping, if needed.
+ * mono_class_inflate_generic_type_with_mempool:
+ * @mempool: a mempool
+ * @type: a type
+ * @context: a generics context
+ *
+ * The same as mono_class_inflate_generic_type, but allocates the MonoType
+ * from mempool if it is non-NULL. If it is NULL, the MonoType is
+ * allocated on the heap and is owned by the caller.
*/
-static MonoType*
+MonoType*
mono_class_inflate_generic_type_with_mempool (MonoMemPool *mempool, MonoType *type, MonoGenericContext *context)
{
MonoType *inflated = NULL;
/* Prevent infinite loops if the class references itself */
class->size_inited = 1;
- class->fields = mono_mempool_alloc0 (class->image->mempool, sizeof (MonoClassField) * top);
+ class->fields = mono_image_alloc0 (class->image, sizeof (MonoClassField) * top);
if (class->generic_container) {
container = class->generic_container;
ifield->generic_type = gfield->type;
field->name = gfield->name;
field->generic_info = ifield;
- /*This memory must come from the image mempool as we don't have a change to free it.*/
+ /*This memory must come from the image mempool as we don't have a chance to free it.*/
field->type = mono_class_inflate_generic_type_with_mempool (class->image->mempool, gfield->type, mono_class_get_context (class));
field->type->attrs = gfield->type->attrs;
if (mono_field_is_deleted (field))
blittable = FALSE;
} else {
MonoClass *field_class = mono_class_from_mono_type (field->type);
+ if (field_class)
+ mono_class_setup_fields (field_class);
if (!field_class || !field_class->blittable)
blittable = FALSE;
}
{
MonoMethod *method;
- method = (MonoMethod *) mono_mempool_alloc0 (class->image->mempool, sizeof (MonoMethodPInvoke));
+ method = (MonoMethod *) mono_image_alloc0 (class->image, sizeof (MonoMethodPInvoke));
method->klass = class;
method->flags = METHOD_ATTRIBUTE_PUBLIC;
method->iflags = METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL;
class->method.count += class->interface_count * count_generic;
}
- methods = mono_mempool_alloc0 (class->image->mempool, sizeof (MonoMethod*) * class->method.count);
+ methods = mono_image_alloc0 (class->image, sizeof (MonoMethod*) * class->method.count);
sig = mono_metadata_signature_alloc (class->image, class->rank);
sig->ret = &mono_defaults.void_class->byval_arg;
for (i = 0; i < class->interface_count; i++)
setup_generic_array_ifaces (class, class->interfaces [i], methods, first_generic + i * count_generic);
} else {
- methods = mono_mempool_alloc (class->image->mempool, sizeof (MonoMethod*) * class->method.count);
+ methods = mono_image_alloc (class->image, sizeof (MonoMethod*) * class->method.count);
for (i = 0; i < class->method.count; ++i) {
int idx = mono_metadata_translate_token_index (class->image, MONO_TABLE_METHOD, class->method.first + i + 1);
methods [i] = mono_get_method (class->image, MONO_TOKEN_METHOD_DEF | idx, class);
if (class->property.count)
mono_class_setup_methods (class);
- properties = mono_mempool_alloc0 (class->image->mempool, sizeof (MonoProperty) * class->property.count);
+ properties = mono_image_alloc0 (class->image, sizeof (MonoProperty) * class->property.count);
for (i = class->property.first; i < last; ++i) {
mono_metadata_decode_table_row (class->image, MONO_TABLE_PROPERTY, i, cols, MONO_PROPERTY_SIZE);
properties [i - class->property.first].parent = class;
}
}
}
+ /*Flush any pending writes as we do double checked locking on class->properties */
+ mono_memory_barrier ();
/* Leave this assignment as the last op in the function */
class->properties = properties;
if (class->event.count)
mono_class_setup_methods (class);
- events = mono_mempool_alloc0 (class->image->mempool, sizeof (MonoEvent) * class->event.count);
+ events = mono_image_alloc0 (class->image, sizeof (MonoEvent) * class->event.count);
for (i = class->event.first; i < last; ++i) {
MonoEvent *event = &events [i - class->event.first];
}
}
}
+ /*Flush any pending writes as we do double checked locking on class->properties */
+ mono_memory_barrier ();
+
/* Leave this assignment as the last op in the function */
class->events = events;
g_assert (class->interface_offsets_count == interface_offsets_count);
} else {
class->interface_offsets_count = interface_offsets_count;
- class->interfaces_packed = mono_mempool_alloc (class->image->mempool, sizeof (MonoClass*) * interface_offsets_count);
- class->interface_offsets_packed = mono_mempool_alloc (class->image->mempool, sizeof (guint16) * interface_offsets_count);
- class->interface_bitmap = mono_mempool_alloc0 (class->image->mempool, (sizeof (guint8) * ((max_iid + 1) >> 3)) + (((max_iid + 1) & 7)? 1 :0));
+ class->interfaces_packed = mono_image_alloc (class->image, sizeof (MonoClass*) * interface_offsets_count);
+ class->interface_offsets_packed = mono_image_alloc (class->image, sizeof (guint16) * interface_offsets_count);
+ class->interface_bitmap = mono_image_alloc0 (class->image, (sizeof (guint8) * ((max_iid + 1) >> 3)) + (((max_iid + 1) & 7)? 1 :0));
for (interface_offsets_count = 0, i = 0; i <= max_iid; i++) {
if (interface_offsets_full [i] != -1) {
class->interface_bitmap [i >> 3] |= (1 << (i & 7));
class->vtable_size = cur_slot;
}
+ /* FIXME: only do this if the class is actually sharable */
+ if (class->valuetype && (class->generic_class || class->generic_container) &&
+ mono_class_generic_sharing_enabled (class)) {
+ for (i = 0; i < max_vtsize; ++i) {
+ if (vtable [i] && vtable [i]->wrapper_type == MONO_WRAPPER_NONE)
+ vtable [i] = mono_marshal_get_static_rgctx_invoke (vtable [i]);
+ }
+ }
+
/* 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)) {
mono_memory_barrier ();
class->vtable = class->parent->vtable;
} else {
- MonoMethod **tmp = mono_mempool_alloc0 (class->image->mempool, sizeof (gpointer) * class->vtable_size);
+ MonoMethod **tmp = mono_image_alloc0 (class->image, sizeof (gpointer) * class->vtable_size);
memcpy (tmp, vtable, sizeof (gpointer) * class->vtable_size);
mono_memory_barrier ();
class->vtable = tmp;
}
}
+/**
+ * mono_method_get_vtable_index:
+ * @method: a method
+ *
+ * Returns the index into the runtime vtable to access the method or,
+ * in the case of a virtual generic method, the virtual generic method
+ * thunk.
+ */
+int
+mono_method_get_vtable_index (MonoMethod *method)
+{
+ if (method->is_inflated && (method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
+ MonoMethodInflated *imethod = (MonoMethodInflated*)method;
+ if (imethod->declaring->is_generic)
+ return imethod->declaring->slot;
+ }
+ return method->slot;
+}
+
static MonoMethod *default_ghc = NULL;
static MonoMethod *default_finalize = NULL;
static int finalize_slot = -1;
g_assert_not_reached ();
}
- name = mono_mempool_alloc (mono_defaults.corlib->mempool, strlen (iname) + strlen (mname) + 1);
+ name = mono_image_alloc (mono_defaults.corlib, strlen (iname) + strlen (mname) + 1);
strcpy (name, iname);
strcpy (name + strlen (iname), mname);
generic_array_method_info [i].name = name;
}
static char*
-concat_two_strings_with_zero (MonoMemPool *pool, const char *s1, const char *s2)
+concat_two_strings_with_zero (MonoImage *image, const char *s1, const char *s2)
{
int len = strlen (s1) + strlen (s2) + 2;
- char *s = mono_mempool_alloc (pool, len);
+ char *s = mono_image_alloc (image, len);
int result;
result = g_snprintf (s, len, "%s%c%s", s1, '\0', s2);
switch (error->exception_type) {
case MONO_EXCEPTION_TYPE_LOAD:
- exception_data = concat_two_strings_with_zero (class->image->mempool, error->class_name, error->assembly_name);
+ exception_data = concat_two_strings_with_zero (class->image, error->class_name, error->assembly_name);
break;
case MONO_EXCEPTION_MISSING_METHOD:
- exception_data = concat_two_strings_with_zero (class->image->mempool, error->class_name, error->member_name);
+ exception_data = concat_two_strings_with_zero (class->image, error->class_name, error->member_name);
break;
case MONO_EXCEPTION_MISSING_FIELD: {
else
class_name = error->klass->name;
- exception_data = concat_two_strings_with_zero (class->image->mempool, class_name, error->member_name);
+ exception_data = concat_two_strings_with_zero (class->image, class_name, error->member_name);
if (name_space)
g_free ((void*)class_name);
else
msg = "Could not load file or assembly '%s' or one of its dependencies.";
- exception_data = concat_two_strings_with_zero (class->image->mempool, msg, error->assembly_name);
+ exception_data = concat_two_strings_with_zero (class->image, msg, error->assembly_name);
break;
}
has_cached_info = mono_class_get_cached_class_info (class, &cached_info);
- if (!class->generic_class && !class->image->dynamic && (!has_cached_info || (has_cached_info && cached_info.has_nested_classes))) {
- 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_mempool (class->nested_classes, class->image->mempool, nclass);
-
- i = mono_metadata_nesting_typedef (class->image, class->type_token, i + 1);
- }
- }
+ if (class->generic_class || class->image->dynamic || !class->type_token || (has_cached_info && !cached_info.has_nested_classes))
+ class->nested_classes_inited = TRUE;
/*
* Computes the size used by the fields, and their locations
}
*/
- if (!MONO_CLASS_IS_INTERFACE (class)) {
+ /* Interfaces and valuetypes are not supposed to have finalizers */
+ if (!(MONO_CLASS_IS_INTERFACE (class) || class->valuetype)) {
MonoMethod *cmethod = NULL;
- if (class->type_token) {
- cmethod = find_method_in_metadata (class, "Finalize", 0, METHOD_ATTRIBUTE_VIRTUAL);
- } else if (class->parent) {
+ if (class->parent) {
/* FIXME: Optimize this */
mono_class_setup_vtable (class);
if (class->exception_type || mono_loader_get_last_error ())
}
if (mono_verifier_is_enabled_for_class (class) && !mono_verifier_verify_class (class)) {
- mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, concat_two_strings_with_zero (class->image->mempool, class->name, class->image->assembly_name));
+ mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, concat_two_strings_with_zero (class->image, class->name, class->image->assembly_name));
class_init_ok = FALSE;
}
class->idepth = 1;
ms = MAX (MONO_DEFAULT_SUPERTABLE_SIZE, class->idepth);
- class->supertypes = mono_mempool_alloc0 (class->image->mempool, sizeof (MonoClass *) * ms);
+ class->supertypes = mono_image_alloc0 (class->image, sizeof (MonoClass *) * ms);
if (class->parent) {
class->supertypes [class->idepth - 1] = class;
name = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAME]);
nspace = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAMESPACE]);
- class = mono_mempool_alloc0 (image->mempool, sizeof (MonoClass));
+ class = mono_image_alloc0 (image, sizeof (MonoClass));
class->name = name;
class->name_space = nspace;
mono_metadata_load_generic_param_constraints (
image, type_token, class->generic_container);
+ if (class->image->assembly_name && !strcmp (class->image->assembly_name, "Mono.Simd") && !strcmp (nspace, "Mono.Simd")) {
+ if (!strncmp (name, "Vector", 6))
+ class->simd_type = !strcmp (name + 6, "4f") || !strcmp (name + 6, "4u") || !strcmp (name + 6, "8u") || !strcmp (name + 6, "16u");
+ }
+
mono_loader_unlock ();
mono_profiler_class_loaded (class, MONO_PROFILE_OK);
/* FIXME: */
image = mono_defaults.corlib;
- klass = param->pklass = mono_mempool_alloc0 (image->mempool, sizeof (MonoClass));
+ klass = param->pklass = mono_image_alloc0 (image, sizeof (MonoClass));
if (param->name)
klass->name = param->name;
else {
- klass->name = mono_mempool_alloc0 (image->mempool, 16);
+ klass->name = mono_image_alloc0 (image, 16);
sprintf ((char*)klass->name, is_mvar ? "!!%d" : "!%d", param->num);
}
klass->name_space = "";
if (count - pos > 0) {
klass->interface_count = count - pos;
- klass->interfaces = mono_mempool_alloc0 (image->mempool, sizeof (MonoClass *) * (count - pos));
+ klass->interfaces = mono_image_alloc0 (image, sizeof (MonoClass *) * (count - pos));
for (i = pos; i < count; i++)
klass->interfaces [i - pos] = param->constraints [i];
}
mono_loader_unlock ();
return result;
}
- result = mono_mempool_alloc0 (image->mempool, sizeof (MonoClass));
+ result = mono_image_alloc0 (image, sizeof (MonoClass));
result->parent = NULL; /* no parent for PTR types */
result->name_space = el_class->name_space;
name = g_strdup_printf ("%s*", el_class->name);
- result->name = mono_mempool_strdup (image->mempool, name);
+ result->name = mono_image_strdup (image, name);
g_free (name);
mono_profiler_class_event (result, MONO_PROFILE_START_LOAD);
mono_class_init (parent);
}
- class = mono_mempool_alloc0 (image->mempool, sizeof (MonoClass));
+ class = mono_image_alloc0 (image, sizeof (MonoClass));
class->image = image;
class->name_space = eclass->name_space;
name [nsize + rank] = '*';
name [nsize + rank + bounded] = ']';
name [nsize + rank + bounded + 1] = 0;
- class->name = mono_mempool_strdup (image->mempool, name);
+ class->name = mono_image_strdup (image, name);
g_free (name);
mono_profiler_class_event (class, MONO_PROFILE_START_LOAD);
/* generic IList, ICollection, IEnumerable */
class->interface_count = 1;
- class->interfaces = mono_mempool_alloc0 (image->mempool, sizeof (MonoClass*) * class->interface_count);
+ class->interfaces = mono_image_alloc0 (image, sizeof (MonoClass*) * class->interface_count);
args [0] = &eclass->byval_arg;
class->interfaces [0] = mono_class_bind_generic_parameters (
class->element_class = eclass;
if ((rank > 1) || bounded) {
- MonoArrayType *at = mono_mempool_alloc0 (image->mempool, sizeof (MonoArrayType));
+ MonoArrayType *at = mono_image_alloc0 (image, sizeof (MonoArrayType));
class->byval_arg.type = MONO_TYPE_ARRAY;
class->byval_arg.data.array = at;
at->eklass = eclass;
}
static MonoClass*
-return_nested_in (MonoClass *class, char *nested) {
+return_nested_in (MonoClass *class, char *nested)
+{
MonoClass *found;
char *s = strchr (nested, '/');
- GList *tmp;
+ gpointer iter = NULL;
if (s) {
*s = 0;
s++;
}
- for (tmp = class->nested_classes; tmp; tmp = tmp->next) {
- found = tmp->data;
+
+ while ((found = mono_class_get_nested_types (class, &iter))) {
if (strcmp (found->name, nested) == 0) {
if (s)
return return_nested_in (found, s);
return NULL;
}
+static MonoClass*
+search_modules (MonoImage *image, const char *name_space, const char *name)
+{
+ MonoTableInfo *file_table = &image->tables [MONO_TABLE_FILE];
+ MonoImage *file_image;
+ MonoClass *class;
+ int i;
+
+ /*
+ * The EXPORTEDTYPES table only contains public types, so have to search the
+ * modules as well.
+ * Note: image->modules contains the contents of the MODULEREF table, while
+ * the real module list is in the FILE table.
+ */
+ for (i = 0; i < file_table->rows; i++) {
+ guint32 cols [MONO_FILE_SIZE];
+ mono_metadata_decode_row (file_table, i, cols, MONO_FILE_SIZE);
+ if (cols [MONO_FILE_FLAGS] == FILE_CONTAINS_NO_METADATA)
+ continue;
+
+ file_image = mono_image_load_file_for_image (image, i + 1);
+ if (file_image) {
+ class = mono_class_from_name (file_image, name_space, name);
+ if (class)
+ return class;
+ }
+ }
+
+ return NULL;
+}
/**
* mono_class_from_name:
if (get_class_from_name) {
gboolean res = get_class_from_name (image, name_space, name, &class);
if (res) {
+ if (!class)
+ class = search_modules (image, name_space, name);
if (nested)
return class ? return_nested_in (class, nested) : NULL;
else
}
if (!token) {
- /*
- * The EXPORTEDTYPES table only contains public types, so have to search the
- * modules as well.
- * Note: image->modules contains the contents of the MODULEREF table, while
- * the real module list is in the FILE table.
- */
- MonoTableInfo *file_table = &image->tables [MONO_TABLE_FILE];
- MonoImage *file_image;
-
- for (i = 0; i < file_table->rows; i++) {
- guint32 cols [MONO_FILE_SIZE];
- mono_metadata_decode_row (file_table, i, cols, MONO_FILE_SIZE);
- if (cols [MONO_FILE_FLAGS] == FILE_CONTAINS_NO_METADATA)
- continue;
-
- file_image = mono_image_load_file_for_image (image, i + 1);
- if (file_image) {
- class = mono_class_from_name (file_image, name_space, name);
- if (class)
- return class;
- }
- }
+ class = search_modules (image, name_space, name);
+ if (class)
+ return class;
}
if (!token)
return class;
} else if ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_ASSEMBLYREF) {
MonoAssembly **references = image->references;
- if (!references [idx - 1])
- mono_assembly_load_reference (image, idx - 1);
+ guint32 assembly_idx;
+
+ assembly_idx = impl >> MONO_IMPLEMENTATION_BITS;
+
+ if (!references [assembly_idx - 1])
+ mono_assembly_load_reference (image, assembly_idx - 1);
g_assert (references == image->references);
- g_assert (references [idx - 1]);
- if (references [idx - 1] == (gpointer)-1)
+ g_assert (references [assembly_idx - 1]);
+ if (references [assembly_idx - 1] == (gpointer)-1)
return NULL;
else
/* FIXME: Cycle detection */
- return mono_class_from_name (references [idx - 1]->image, name_space, name);
+ return mono_class_from_name (references [assembly_idx - 1]->image, name_space, name);
} else {
g_error ("not yet implemented");
}
* interface_offsets set.
*/
return mono_reflection_call_is_assignable_to (oklass, klass);
-
+ if (!oklass->interface_bitmap)
+ /* Happens with generic instances of not-yet created dynamic types */
+ return FALSE;
if (MONO_CLASS_IMPLEMENTS_INTERFACE (oklass, klass->interface_id))
return TRUE;
}
return mono_class_is_assignable_from (klass->cast_class, oklass->cast_class);
- } else if (mono_class_is_nullable (klass))
- return (mono_class_is_assignable_from (klass->cast_class, oklass));
- else if (klass == mono_defaults.object_class)
+ } else if (mono_class_is_nullable (klass)) {
+ if (mono_class_is_nullable (oklass))
+ return mono_class_is_assignable_from (klass->cast_class, oklass->cast_class);
+ else
+ return mono_class_is_assignable_from (klass->cast_class, oklass);
+ } else if (klass == mono_defaults.object_class)
return TRUE;
return mono_class_has_parent (oklass, klass);
mono_class_get_nested_types (MonoClass* klass, gpointer *iter)
{
GList *item;
+ int i;
+
if (!iter)
return NULL;
if (!klass->inited)
mono_class_init (klass);
+ if (!klass->nested_classes_inited) {
+ if (!klass->type_token)
+ klass->nested_classes_inited = TRUE;
+ mono_loader_lock ();
+ if (!klass->nested_classes_inited) {
+ i = mono_metadata_nesting_typedef (klass->image, klass->type_token, 1);
+ while (i) {
+ MonoClass* nclass;
+ guint32 cols [MONO_NESTED_CLASS_SIZE];
+ mono_metadata_decode_row (&klass->image->tables [MONO_TABLE_NESTEDCLASS], i - 1, cols, MONO_NESTED_CLASS_SIZE);
+ nclass = mono_class_create_from_typedef (klass->image, MONO_TOKEN_TYPE_DEF | cols [MONO_NESTED_CLASS_NESTED]);
+ klass->nested_classes = g_list_prepend_mempool (klass->nested_classes, klass->image->mempool, nclass);
+
+ i = mono_metadata_nesting_typedef (klass->image, klass->type_token, i + 1);
+ }
+ }
+ mono_memory_barrier ();
+ klass->nested_classes_inited = TRUE;
+ mono_loader_unlock ();
+ }
+
if (!*iter) {
/* start from the first */
if (klass->nested_classes) {
static gboolean
is_nesting_type (MonoClass *outer_klass, MonoClass *inner_klass)
{
+ outer_klass = mono_class_get_generic_type_definition (outer_klass);
+ inner_klass = mono_class_get_generic_type_definition (inner_klass);
do {
if (outer_klass == inner_klass)
return TRUE;
return TRUE;
if (!accessed || !accessing)
return FALSE;
+ mono_assembly_load_friends (accessed);
for (tmp = accessed->friend_assembly_names; tmp; tmp = tmp->next) {
MonoAssemblyName *friend = tmp->data;
/* Be conservative with checks */
{
int i;
for (i = 0; i < ginst->type_argc; ++i) {
- if (!can_access_type (access_klass, mono_class_from_mono_type (ginst->type_argv[i])))
+ MonoType *type = ginst->type_argv[i];
+ if (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)
+ continue;
+ if (!can_access_type (access_klass, mono_class_from_mono_type (type)))
return FALSE;
}
return TRUE;
gboolean
mono_class_generic_sharing_enabled (MonoClass *class)
{
-#if defined(__i386__) || defined(__x86_64__)
- static int generic_sharing = MONO_GENERIC_SHARING_CORLIB;
+#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__ppc__) || defined(__powerpc__)
+ static gboolean supported = TRUE;
#else
- static int generic_sharing = MONO_GENERIC_SHARING_NONE;
+ /* Not supported by the JIT backends */
+ static gboolean supported = FALSE;
#endif
+ static int generic_sharing = MONO_GENERIC_SHARING_NONE;
static gboolean inited = FALSE;
if (!inited) {
const char *option;
+ if (supported)
+ generic_sharing = MONO_GENERIC_SHARING_ALL;
+ else
+ generic_sharing = MONO_GENERIC_SHARING_NONE;
+
if ((option = g_getenv ("MONO_GENERIC_SHARING"))) {
if (strcmp (option, "corlib") == 0)
generic_sharing = MONO_GENERIC_SHARING_CORLIB;
+ else if (strcmp (option, "collections") == 0)
+ generic_sharing = MONO_GENERIC_SHARING_COLLECTIONS;
else if (strcmp (option, "all") == 0)
generic_sharing = MONO_GENERIC_SHARING_ALL;
else if (strcmp (option, "none") == 0)
g_warning ("Unknown generic sharing option `%s'.", option);
}
+ if (!supported)
+ generic_sharing = MONO_GENERIC_SHARING_NONE;
+
inited = TRUE;
}
return TRUE;
case MONO_GENERIC_SHARING_CORLIB :
return class->image == mono_defaults.corlib;
+ case MONO_GENERIC_SHARING_COLLECTIONS:
+ if (class->image != mono_defaults.corlib)
+ return FALSE;
+ while (class->nested_in)
+ class = class->nested_in;
+ return g_str_has_prefix (class->name_space, "System.Collections.Generic");
default:
g_assert_not_reached ();
}