static gboolean do_mono_metadata_type_equal (MonoType *t1, MonoType *t2, gboolean signature_only);
static gboolean mono_metadata_class_equal (MonoClass *c1, MonoClass *c2, gboolean signature_only);
+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);
g_hash_table_insert (type_cache, (gpointer) &builtin_types [i], (gpointer) &builtin_types [i]);
}
+/**
+ * mono_metadata_cleanup:
+ *
+ * Free all resources used by this module.
+ * This is a Mono runtime internal function.
+ */
+void
+mono_metadata_cleanup (void)
+{
+ g_hash_table_destroy (type_cache);
+ g_hash_table_destroy (generic_inst_cache);
+ g_hash_table_destroy (generic_class_cache);
+}
+
/**
* mono_metadata_parse_type:
* @m: metadata context
* this MonoGenericContainer.
* This is a Mono runtime internal function.
*
+ * LOCKING: Assumes the loader lock is held.
+ *
* Returns: a #MonoType structure representing the decoded type.
*/
MonoType*
}
if (count) {
- type = g_malloc0 (sizeof (MonoType) + ((gint32)count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod));
+ type = mono_mempool_alloc0 (m->mempool, sizeof (MonoType) + ((gint32)count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod));
type->num_mods = count;
if (count > 64)
g_warning ("got more than 64 modifiers in type");
/* printf ("%x %x %c %s\n", type->attrs, type->num_mods, type->pinned ? 'p' : ' ', mono_type_full_name (type)); */
- if (type == &stype)
- type = g_memdup (&stype, sizeof (MonoType));
+ if (type == &stype) {
+ type = mono_mempool_alloc (m->mempool, sizeof (MonoType));
+ memcpy (type, &stype, sizeof (MonoType));
+ }
return type;
}
+/*
+ * LOCKING: Assumes the loader lock is held.
+ */
MonoType*
mono_metadata_parse_type (MonoImage *m, MonoParseTypeMode mode, short opt_attrs,
const char *ptr, const char **rptr)
* The return type and the params types need to be filled later.
* This is a Mono runtime internal function.
*
+ * LOCKING: Assumes the loader lock is held.
+ *
* Returns: the new MonoMethodSignature structure.
*/
MonoMethodSignature*
{
MonoMethodSignature *sig;
- /* later we want to allocate signatures with mempools */
- sig = g_malloc0 (sizeof (MonoMethodSignature) + ((gint32)nparams - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
+ sig = mono_mempool_alloc0 (m->mempool, sizeof (MonoMethodSignature) + ((gint32)nparams - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
sig->param_count = nparams;
sig->sentinelpos = -1;
* Decode a method signature stored at @ptr.
* This is a Mono runtime internal function.
*
+ * LOCKING: Assumes the loader lock is held.
+ *
* Returns: a MonoMethodSignature describing the signature.
*/
MonoMethodSignature *
if (*ptr == MONO_TYPE_SENTINEL) {
if (method->call_convention != MONO_CALL_VARARG || def)
g_error ("found sentinel for methoddef or no vararg method");
+ if (method->sentinelpos >= 0)
+ g_error ("found sentinel twice in the same signature");
method->sentinelpos = i;
ptr++;
}
is_open = mono_class_is_open_constructed_type (method->params [i]);
}
+ /* The sentinel could be missing if the caller does not pass any additional arguments */
+ if (!def && method->call_convention == MONO_CALL_VARARG && method->sentinelpos < 0)
+ method->sentinelpos = method->param_count;
+
method->has_type_parameters = is_open;
if (def && (method->call_convention == MONO_CALL_VARARG))
if (sig->params [i])
mono_metadata_free_type (sig->params [i]);
}
-
- g_free (sig);
}
/*
return mono_metadata_lookup_generic_inst (ginst);
}
-static void
+static gboolean
do_mono_metadata_parse_generic_class (MonoType *type, MonoImage *m, MonoGenericContainer *container,
const char *ptr, const char **rptr)
{
igclass->klass = g_new0 (MonoClass, 1);
gtype = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
+ if (gtype == NULL)
+ return FALSE;
gclass->container_class = gklass = mono_class_from_mono_type (gtype);
g_assert (gklass->generic_container);
if (rptr)
*rptr = ptr;
+ /* If we failed to parse, return, the error has been flagged. */
+ if (gclass->inst == NULL)
+ return FALSE;
+
/*
* We may be called multiple times on different metadata to create the same
* instantiated type. This happens for instance if we're part of a method or
g_free (gclass);
type->data.generic_class = cached;
- return;
+ return TRUE;
} else {
g_hash_table_insert (generic_class_cache, gclass, gclass);
sizeof (MonoGenericContext) +
gclass->inst->type_argc * sizeof (MonoType);
}
+ return TRUE;
}
/*
do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer *container,
const char *ptr, const char **rptr)
{
+ gboolean ok = TRUE;
type->type = mono_metadata_decode_value (ptr, &ptr);
switch (type->type){
type->data.generic_param = mono_metadata_parse_generic_param (m, container, type->type, ptr, &ptr);
break;
case MONO_TYPE_GENERICINST:
- do_mono_metadata_parse_generic_class (type, m, container, ptr, &ptr);
+ ok = do_mono_metadata_parse_generic_class (type, m, container, ptr, &ptr);
break;
default:
g_error ("type 0x%02x not handled in do_mono_metadata_parse_type", type->type);
if (rptr)
*rptr = ptr;
- return TRUE;
+ return ok;
}
/*
* mono_metadata_free_type:
* @type: type to free
*
- * Free the memory allocated for type @type.
+ * Free the memory allocated for type @type which is assumed to be created by
+ * mono_metadata_parse_type ().
*/
void
mono_metadata_free_type (MonoType *type)
mono_metadata_free_array (type->data.array);
break;
}
- g_free (type);
+
+ /* Allocated from a mempool, no need to free it */
}
#if 0
int i;
mh->num_clauses = is_fat ? sect_data_len / 24: sect_data_len / 12;
/* we could just store a pointer if we don't need to byteswap */
- mh->clauses = g_new0 (MonoExceptionClause, mh->num_clauses);
+ mh->clauses = mono_mempool_alloc0 (m->mempool, sizeof (MonoExceptionClause) * mh->num_clauses);
for (i = 0; i < mh->num_clauses; ++i) {
MonoExceptionClause *ec = &mh->clauses [i];
guint32 tof_value;
pos = start;
while (pos < tdef->rows) {
+ MonoClass *iface;
+
mono_metadata_decode_row (tdef, pos, cols, MONO_INTERFACEIMPL_SIZE);
if (cols [MONO_INTERFACEIMPL_CLASS] != loc.idx)
break;
- result [pos - start] = mono_class_get_full (
+ iface = mono_class_get_full (
meta, mono_metadata_token_from_dor (cols [MONO_INTERFACEIMPL_INTERFACE]), context);
+ if (iface == NULL)
+ return FALSE;
+ result [pos - start] = iface;
++pos;
}
*count = pos - start;
MonoClass *container_class;
gclass = mono_get_inflated_generic_class (t->data.generic_class);
- g_assert (!gclass->generic_class.inst->is_open);
- g_assert (!gclass->klass->generic_container);
+ // g_assert (!gclass->generic_class.inst->is_open);
+ // g_assert (!gclass->klass->generic_container);
container_class = gclass->generic_class.container_class;
return FALSE;
}
+static gboolean
+mono_metadata_fnptr_equal (MonoMethodSignature *s1, MonoMethodSignature *s2, gboolean signature_only)
+{
+ gpointer iter1 = 0, iter2 = 0;
+
+ if (s1 == s2)
+ return TRUE;
+ if (s1->call_convention != s2->call_convention)
+ return FALSE;
+ if (s1->sentinelpos != s2->sentinelpos)
+ return FALSE;
+ if (s1->hasthis != s2->hasthis)
+ return FALSE;
+ if (s1->explicit_this != s2->explicit_this)
+ return FALSE;
+ if (! do_mono_metadata_type_equal (s1->ret, s2->ret, signature_only))
+ return FALSE;
+ if (s1->param_count != s2->param_count)
+ return FALSE;
+
+ while (TRUE) {
+ MonoType *t1 = mono_signature_get_params (s1, &iter1);
+ MonoType *t2 = mono_signature_get_params (s2, &iter2);
+
+ if (t1 == NULL || t2 == NULL)
+ return (t1 == t2);
+ if (! do_mono_metadata_type_equal (t1, t2, signature_only))
+ return FALSE;
+ }
+}
+
/*
* mono_metadata_type_equal:
* @t1: a type
case MONO_TYPE_MVAR:
return mono_metadata_generic_param_equal (
t1->data.generic_param, t2->data.generic_param, signature_only);
+ case MONO_TYPE_FNPTR:
+ return mono_metadata_fnptr_equal (t1->data.method, t2->data.method, signature_only);
default:
g_error ("implement type compare for %0x!", t1->type);
return FALSE;
return TRUE;
}
+/**
+ * mono_metadata_type_dup_mp:
+ * @image: image type is defined in
+ * @original: type to duplicate
+ *
+ * Returns: copy of type allocated from mempool.
+ */
+MonoType *
+mono_metadata_type_dup_mp (MonoImage *image, const MonoType *original)
+{
+ MonoType *r = NULL;
+ mono_loader_lock ();
+ r = mono_mempool_alloc0 (image->mempool, sizeof(MonoType));
+ mono_loader_unlock ();
+ *r = *original;
+ /* FIXME: we don't handle these yet because they need to duplicate memory
+ * but the current routines used are not using the mempools
+ */
+ if (original->type == MONO_TYPE_PTR ||
+ original->type == MONO_TYPE_ARRAY ||
+ original->type == MONO_TYPE_FNPTR)
+ g_assert_not_reached ();
+ return r;
+}
+
guint
mono_signature_hash (MonoMethodSignature *sig)
{
gint32 i, num;
guint32 cols [MONO_METHODIMPL_SIZE];
MonoMethod **result;
-
+ gint32 ok = TRUE;
+
*overrides = NULL;
if (num_overrides)
*num_overrides = 0;
num = end - start;
result = g_new (MonoMethod*, num * 2);
for (i = 0; i < num; ++i) {
+ MonoMethod *method;
+
mono_metadata_decode_row (tdef, start + i, cols, MONO_METHODIMPL_SIZE);
- result [i * 2] = method_from_method_def_or_ref (
+ method = method_from_method_def_or_ref (
image, cols [MONO_METHODIMPL_DECLARATION], generic_context);
- result [i * 2 + 1] = method_from_method_def_or_ref (
+ if (method == NULL)
+ ok = FALSE;
+ result [i * 2] = method;
+ method = method_from_method_def_or_ref (
image, cols [MONO_METHODIMPL_BODY], generic_context);
+ if (method == NULL)
+ ok = FALSE;
+ result [i * 2 + 1] = method;
}
*overrides = result;
if (num_overrides)
*num_overrides = num;
- return TRUE;
+ return ok;
}
/**