*/
#include <config.h>
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "verify-internals.h"
#include "class.h"
#include "marshal.h"
-#include "gc-internal.h"
#include "debug-helpers.h"
#include <mono/utils/mono-error-internals.h>
static gboolean mono_metadata_fnptr_equal (MonoMethodSignature *s1, MonoMethodSignature *s2, gboolean signature_only);
static gboolean _mono_metadata_generic_class_equal (const MonoGenericClass *g1, const MonoGenericClass *g2,
gboolean signature_only);
-static GSList* free_generic_inst_dependents (MonoGenericInst *ginst);
static void free_generic_inst (MonoGenericInst *ginst);
-static GSList* free_generic_class_dependents (MonoGenericClass *ginst);
static void free_generic_class (MonoGenericClass *ginst);
static void free_inflated_method (MonoMethodInflated *method);
static void free_inflated_signature (MonoInflatedMethodSignature *sig);
n = MAX (n, meta->tables [MONO_TABLE_METHOD].rows);
n = MAX (n, meta->tables [MONO_TABLE_MODULEREF].rows);
n = MAX (n, meta->tables [MONO_TABLE_TYPESPEC].rows);
- n = MAX (n, meta->tables [MONO_TABLE_MEMBERREF].rows);
/* 3 bits to encode */
field_size = rtsize (n, 16 - 3);
const char *
mono_metadata_string_heap (MonoImage *meta, guint32 index)
{
+ g_assert (index < meta->heap_strings.size);
g_return_val_if_fail (index < meta->heap_strings.size, "");
return meta->heap_strings.data + index;
}
const char *
mono_metadata_user_string (MonoImage *meta, guint32 index)
{
+ g_assert (index < meta->heap_us.size);
g_return_val_if_fail (index < meta->heap_us.size, "");
return meta->heap_us.data + index;
}
const char *
mono_metadata_blob_heap (MonoImage *meta, guint32 index)
{
+ g_assert (index < meta->heap_blob.size);
g_return_val_if_fail (index < meta->heap_blob.size, "");/*FIXME shouldn't we return NULL and check for index == 0?*/
return meta->heap_blob.data + index;
}
g_free (set);
}
+static void
+mono_image_set_lock (MonoImageSet *set)
+{
+ EnterCriticalSection (&set->lock);
+}
+
+static void
+mono_image_set_unlock (MonoImageSet *set)
+{
+ LeaveCriticalSection (&set->lock);
+}
+
+gpointer
+mono_image_set_alloc (MonoImageSet *set, guint size)
+{
+ gpointer res;
+
+ mono_image_set_lock (set);
+ if (!set->mempool)
+ set->mempool = mono_mempool_new_size (1024);
+ res = mono_mempool_alloc (set->mempool, size);
+ mono_image_set_unlock (set);
+
+ return res;
+}
+
+gpointer
+mono_image_set_alloc0 (MonoImageSet *set, guint size)
+{
+ gpointer res;
+
+ mono_image_set_lock (set);
+ if (!set->mempool)
+ set->mempool = mono_mempool_new_size (1024);
+ res = mono_mempool_alloc0 (set->mempool, size);
+ mono_image_set_unlock (set);
+
+ return res;
+}
+
+char*
+mono_image_set_strdup (MonoImageSet *set, const char *s)
+{
+ char *res;
+
+ mono_image_set_lock (set);
+ if (!set->mempool)
+ set->mempool = mono_mempool_new_size (1024);
+ res = mono_mempool_strdup (set->mempool, s);
+ mono_image_set_unlock (set);
+
+ return res;
+}
+
/*
* Structure used by the collect_..._images functions to store the image list.
*/
//check_image_sets (image);
- /* The data structures could reference each other so we delete them in two phases */
+ /*
+ * The data structures could reference each other so we delete them in two phases.
+ * This is required because of the hashing functions in gclass/ginst_cache.
+ */
ginst_data.image = gclass_data.image = image;
ginst_data.list = gclass_data.list = NULL;
mono_loader_lock ();
/* Delete the removed items */
for (l = ginst_data.list; l; l = l->next)
- free_list = g_slist_concat (free_generic_inst_dependents (l->data), free_list);
+ free_generic_inst (l->data);
for (l = gclass_data.list; l; l = l->next)
- free_list = g_slist_concat (free_generic_class_dependents (l->data), free_list);
+ free_generic_class (l->data);
g_slist_free (ginst_data.list);
g_slist_free (gclass_data.list);
/* delete_image_set () modifies the lists so make a copy */
}
static void
-free_list_with_data (GSList *l)
-{
- while (l) {
- g_free (l->data);
- l = g_slist_delete_link (l, l);
- }
-}
-
-static GSList*
-free_generic_inst_dependents (MonoGenericInst *ginst)
+free_generic_inst (MonoGenericInst *ginst)
{
int i;
+ /* The ginst itself is allocated from the image set mempool */
for (i = 0; i < ginst->type_argc; ++i)
mono_metadata_free_type (ginst->type_argv [i]);
- return g_slist_prepend (NULL, ginst);
-}
-
-static void
-free_generic_inst (MonoGenericInst *ginst)
-{
- free_list_with_data (free_generic_inst_dependents (ginst));
-}
-
-static GSList*
-free_generic_class_dependents (MonoGenericClass *gclass)
-{
- GSList *l = NULL;
- int i;
-
- /* FIXME: The dynamic case */
- if (gclass->cached_class && !gclass->cached_class->image->dynamic && !mono_generic_class_is_generic_type_definition (gclass)) {
- MonoClass *class = gclass->cached_class;
-
- /* Allocated in mono_class_init () */
- g_free (class->methods);
- if (class->ext) {
- g_free (class->ext->properties);
- g_free (class->ext->field_def_values);
- }
- /* Allocated in mono_class_setup_fields () */
- g_free (class->fields);
- /* Allocated in mono_class_setup_vtable_general () */
- g_free (class->vtable);
- /* Allocated in mono_generic_class_get_class () */
- g_free (class->interfaces);
- /* Allocated in setup_interface_offsets () */
- g_free (class->interfaces_packed);
- g_free (class->interface_offsets_packed);
- g_free (class->interface_bitmap);
- /* Allocated in mono_class_setup_supertypes () */
- g_free (class->supertypes);
- l = g_slist_prepend (l, class);
- } else if (gclass->is_dynamic) {
- MonoDynamicGenericClass *dgclass = (MonoDynamicGenericClass *)gclass;
-
- for (i = 0; i < dgclass->count_fields; ++i) {
- MonoClassField *field = dgclass->fields + i;
- mono_metadata_free_type (field->type);
- g_free ((char*)field->name);
-#if HAVE_SGEN_GC
- MONO_GC_UNREGISTER_ROOT (dgclass->field_objects [i]);
-#endif
- }
-
- g_free (dgclass->methods);
- g_free (dgclass->ctors);
- g_free (dgclass->fields);
- g_free (dgclass->field_objects);
- g_free (dgclass->field_generic_types);
- if (!mono_generic_class_is_generic_type_definition (gclass))
- l = g_slist_prepend (l, gclass->cached_class);
- }
- return g_slist_prepend (l, gclass);
}
static void
free_generic_class (MonoGenericClass *gclass)
{
- free_list_with_data (free_generic_class_dependents (gclass));
+ /* The gclass itself is allocated from the image set mempool */
+ if (gclass->is_dynamic)
+ mono_reflection_free_dynamic_generic_class (gclass);
+ if (gclass->cached_class && gclass->cached_class->interface_id)
+ mono_unload_interface_id (gclass->cached_class);
}
static void
break;
is_open = (i < type_argc);
- ginst = alloca (size);
-#ifndef MONO_SMALL_CONFIG
- ginst->id = 0;
-#endif
+ ginst = g_alloca (size);
+ memset (ginst, 0, sizeof (MonoGenericInst));
ginst->is_open = is_open;
ginst->type_argc = type_argc;
memcpy (ginst->type_argv, type_argv, type_argc * sizeof (MonoType *));
ginst = g_hash_table_lookup (set->ginst_cache, ginst);
if (!ginst) {
- ginst = g_malloc (size);
+ ginst = mono_image_set_alloc0 (set, size);
#ifndef MONO_SMALL_CONFIG
ginst->id = ++next_generic_inst_id;
#endif
}
if (is_dynamic) {
- MonoDynamicGenericClass *dgclass = g_new0 (MonoDynamicGenericClass, 1);
+ MonoDynamicGenericClass *dgclass = mono_image_set_new0 (set, MonoDynamicGenericClass, 1);
gclass = &dgclass->generic_class;
gclass->is_dynamic = 1;
} else {
- gclass = g_new0 (MonoGenericClass, 1);
+ gclass = mono_image_set_new0 (set, MonoGenericClass, 1);
}
gclass->is_tb_open = is_tb_open;
gclass->container_class = container_class;
gclass->context.class_inst = inst;
gclass->context.method_inst = NULL;
+ gclass->owner = set;
if (inst == container_class->generic_container->context.class_inst && !is_tb_open)
gclass->cached_class = container_class;
return NULL;
}
+static gboolean
+compare_type_literals (int class_type, int type_type)
+{
+ /* byval_arg.type can be zero if we're decoding a type that references a class been loading.
+ * See mcs/test/gtest-440. and #650936.
+ * FIXME This better be moved to the metadata verifier as it can catch more cases.
+ */
+ if (!class_type)
+ return TRUE;
+ /* NET 1.1 assemblies might encode string and object in a denormalized way.
+ * See #675464.
+ */
+ if (type_type == MONO_TYPE_CLASS && (class_type == MONO_TYPE_STRING || class_type == MONO_TYPE_OBJECT))
+ return TRUE;
+ return class_type == type_type;
+}
+
/*
* do_mono_metadata_parse_type:
* @type: MonoType to be filled in with the return value
type->data.klass = class;
if (!class)
return FALSE;
- /* byval_arg.type can be zero if we're decoding a type that references a class been loading.
- * See mcs/test/gtest-440. and #650936.
- * FIXME This better be moved to the metadata verifier as it can catch more cases.
- */
- if (class->byval_arg.type && class->byval_arg.type != type->type) {
- printf ("me [%x] it [%x] -- '%s'\n", type->type, type->data.klass->byval_arg.type, mono_type_full_name (type));
+ if (!compare_type_literals (class->byval_arg.type, type->type))
return FALSE;
- }
break;
}
case MONO_TYPE_SZARRAY: {
*
* Returns: the 1-based index into the TypeDef table of the type
* where the type described by @index is nested.
- * Retruns 0 if @index describes a non-nested type.
+ * Returns 0 if @index describes a non-nested type.
*/
guint32
mono_metadata_nested_in_typedef (MonoImage *meta, guint32 index)
}
#endif
-#ifndef __GNUC__
-/*#define __alignof__(a) sizeof(a)*/
-#define __alignof__(type) G_STRUCT_OFFSET(struct { char c; type x; }, x)
-#endif
+#define abi__alignof__(type) G_STRUCT_OFFSET(struct { char c; type x; }, x)
/*
* mono_type_size:
return 0;
}
if (t->byref) {
- *align = __alignof__(gpointer);
+ *align = abi__alignof__(gpointer);
return sizeof (gpointer);
}
*align = 1;
return 0;
case MONO_TYPE_BOOLEAN:
- *align = __alignof__(gint8);
+ *align = abi__alignof__(gint8);
return 1;
case MONO_TYPE_I1:
case MONO_TYPE_U1:
- *align = __alignof__(gint8);
+ *align = abi__alignof__(gint8);
return 1;
case MONO_TYPE_CHAR:
case MONO_TYPE_I2:
case MONO_TYPE_U2:
- *align = __alignof__(gint16);
+ *align = abi__alignof__(gint16);
return 2;
case MONO_TYPE_I4:
case MONO_TYPE_U4:
- *align = __alignof__(gint32);
+ *align = abi__alignof__(gint32);
return 4;
case MONO_TYPE_R4:
- *align = __alignof__(float);
+ *align = abi__alignof__(float);
return 4;
case MONO_TYPE_I8:
case MONO_TYPE_U8:
- *align = __alignof__(gint64);
+ *align = abi__alignof__(gint64);
return 8;
case MONO_TYPE_R8:
- *align = __alignof__(double);
+ *align = abi__alignof__(double);
return 8;
case MONO_TYPE_I:
case MONO_TYPE_U:
- *align = __alignof__(gpointer);
+ *align = abi__alignof__(gpointer);
return sizeof (gpointer);
case MONO_TYPE_STRING:
- *align = __alignof__(gpointer);
+ *align = abi__alignof__(gpointer);
return sizeof (gpointer);
case MONO_TYPE_OBJECT:
- *align = __alignof__(gpointer);
+ *align = abi__alignof__(gpointer);
return sizeof (gpointer);
case MONO_TYPE_VALUETYPE: {
if (t->data.klass->enumtype)
case MONO_TYPE_PTR:
case MONO_TYPE_FNPTR:
case MONO_TYPE_ARRAY:
- *align = __alignof__(gpointer);
+ *align = abi__alignof__(gpointer);
return sizeof (gpointer);
case MONO_TYPE_TYPEDBYREF:
return mono_class_value_size (mono_defaults.typed_reference_class, (guint32*)align);
else
return mono_class_value_size (mono_class_from_mono_type (t), (guint32*)align);
} else {
- *align = __alignof__(gpointer);
+ *align = abi__alignof__(gpointer);
return sizeof (gpointer);
}
}
case MONO_TYPE_VAR:
case MONO_TYPE_MVAR:
/* FIXME: Martin, this is wrong. */
- *align = __alignof__(gpointer);
+ *align = abi__alignof__(gpointer);
return sizeof (gpointer);
default:
g_error ("mono_type_size: type 0x%02x unknown", t->type);
int tmp;
#if SIZEOF_VOID_P == SIZEOF_REGISTER
int stack_slot_size = sizeof (gpointer);
- int stack_slot_align = __alignof__ (gpointer);
+ int stack_slot_align = abi__alignof__ (gpointer);
#elif SIZEOF_VOID_P < SIZEOF_REGISTER
int stack_slot_size = SIZEOF_REGISTER;
int stack_slot_align = SIZEOF_REGISTER;
*align = stack_slot_align;
return stack_slot_size * 3;
case MONO_TYPE_R4:
- *align = __alignof__(float);
+ *align = abi__alignof__(float);
return sizeof (float);
case MONO_TYPE_I8:
case MONO_TYPE_U8:
- *align = __alignof__(gint64);
+ *align = abi__alignof__(gint64);
return sizeof (gint64);
case MONO_TYPE_R8:
- *align = __alignof__(double);
+ *align = abi__alignof__(double);
return sizeof (double);
case MONO_TYPE_VALUETYPE: {
guint32 size;
return TRUE;
if (mono_generic_param_num (p1) != mono_generic_param_num (p2))
return FALSE;
+ if (p1->serial != p2->serial)
+ return FALSE;
/*
* We have to compare the image as well because if we didn't,
if (signature_only &&
(c1->byval_arg.type == MONO_TYPE_SZARRAY) && (c2->byval_arg.type == MONO_TYPE_SZARRAY))
return mono_metadata_class_equal (c1->byval_arg.data.klass, c2->byval_arg.data.klass, signature_only);
+ if (signature_only &&
+ (c1->byval_arg.type == MONO_TYPE_ARRAY) && (c2->byval_arg.type == MONO_TYPE_ARRAY))
+ return do_mono_metadata_type_equal (&c1->byval_arg, &c2->byval_arg, signature_only);
return FALSE;
}
const char *ptr;
guint32 len;
MonoType *type, *type2;
- MonoType stack_type;
mono_loader_lock ();
len = mono_metadata_decode_value (ptr, &ptr);
- type = &stack_type;
- memset (type, 0, MONO_SIZEOF_TYPE);
-
- if (*ptr == MONO_TYPE_BYREF) {
- type->byref = 1;
- ptr++;
- }
-
- if (!do_mono_metadata_parse_type (type, image, NULL, FALSE, ptr, &ptr)) {
+ type = mono_metadata_parse_type_internal (image, NULL, MONO_PARSE_TYPE, 0, TRUE, ptr, &ptr);
+ if (!type) {
mono_loader_unlock ();
return NULL;
}
return type2;
}
- type2 = mono_image_alloc (image, MONO_SIZEOF_TYPE);
- memcpy (type2, type, MONO_SIZEOF_TYPE);
+ type2 = mono_metadata_type_dup (image, type);
g_hash_table_insert (image->typespec_cache, GUINT_TO_POINTER (type_spec), type2);
+ mono_metadata_free_type (type);
mono_loader_unlock ();
}
*conv = MONO_MARSHAL_CONV_BOOL_I4;
return MONO_NATIVE_BOOLEAN;
- case MONO_TYPE_CHAR: return MONO_NATIVE_U2;
+ case MONO_TYPE_CHAR:
+ if (mspec) {
+ switch (mspec->native) {
+ case MONO_NATIVE_U2:
+ case MONO_NATIVE_U1:
+ return mspec->native;
+ default:
+ g_error ("cant marshal char to native type %02x", mspec->native);
+ }
+ }
+ return unicode ? MONO_NATIVE_U2 : MONO_NATIVE_U1;
case MONO_TYPE_I1: return MONO_NATIVE_I1;
case MONO_TYPE_U1: return MONO_NATIVE_U1;
case MONO_TYPE_I2: return MONO_NATIVE_I2;