}
static MonoType*
-inflate_generic_type (MonoType *type, MonoGenericContext *context)
+inflate_generic_type (MonoMemPool *mempool, MonoType *type, MonoGenericContext *context)
{
switch (type->type) {
case MONO_TYPE_MVAR: {
* while the VAR/MVAR duplicates a type from the context. So, we need to ensure that the
* ->byref and ->attrs from @type are propagated to the returned type.
*/
- nt = mono_metadata_type_dup (NULL, inst->type_argv [num]);
+ nt = mono_metadata_type_dup (mempool, inst->type_argv [num]);
nt->byref = type->byref;
nt->attrs = type->attrs;
return nt;
return NULL;
if (num >= inst->type_argc)
g_error ("VAR %d (%s) cannot be expanded in this context with %d instantiations", num, type->data.generic_param->name, inst->type_argc);
- nt = mono_metadata_type_dup (NULL, inst->type_argv [num]);
+ nt = mono_metadata_type_dup (mempool, inst->type_argv [num]);
nt->byref = type->byref;
nt->attrs = type->attrs;
return nt;
}
case MONO_TYPE_SZARRAY: {
MonoClass *eclass = type->data.klass;
- MonoType *nt, *inflated = inflate_generic_type (&eclass->byval_arg, context);
+ MonoType *nt, *inflated = inflate_generic_type (NULL, &eclass->byval_arg, context);
if (!inflated)
return NULL;
- nt = mono_metadata_type_dup (NULL, type);
+ nt = mono_metadata_type_dup (mempool, type);
nt->data.klass = mono_class_from_mono_type (inflated);
mono_metadata_free_type (inflated);
return nt;
}
case MONO_TYPE_ARRAY: {
MonoClass *eclass = type->data.array->eklass;
- MonoType *nt, *inflated = inflate_generic_type (&eclass->byval_arg, context);
+ MonoType *nt, *inflated = inflate_generic_type (NULL, &eclass->byval_arg, context);
if (!inflated)
return NULL;
- nt = mono_metadata_type_dup (NULL, type);
+ nt = mono_metadata_type_dup (mempool, type);
nt->data.array = g_memdup (nt->data.array, sizeof (MonoArrayType));
nt->data.array->eklass = mono_class_from_mono_type (inflated);
mono_metadata_free_type (inflated);
if (gclass == type->data.generic_class)
return NULL;
- nt = mono_metadata_type_dup (NULL, type);
+ nt = mono_metadata_type_dup (mempool, type);
nt->data.generic_class = gclass;
return nt;
}
gclass = mono_metadata_lookup_generic_class (klass, inst, klass->image->dynamic);
- nt = mono_metadata_type_dup (NULL, type);
+ nt = mono_metadata_type_dup (mempool, type);
nt->type = MONO_TYPE_GENERICINST;
nt->data.generic_class = gclass;
return nt;
return class->generic_class ? mono_generic_class_get_context (class->generic_class) : NULL;
}
+/*
+ * This method allows specifying a mempool to do type duping, if needed.
+ */
+static MonoType*
+mono_class_inflate_generic_type_with_mempool (MonoMemPool *mempool, MonoType *type, MonoGenericContext *context)
+{
+ MonoType *inflated = NULL;
+
+ if (context)
+ inflated = inflate_generic_type (mempool, type, context);
+
+ if (!inflated)
+ return mono_metadata_type_dup (mempool, type);
+
+ mono_stats.inflated_type_count++;
+ return inflated;
+}
+
/*
* mono_class_inflate_generic_type:
* @type: a type
MonoType*
mono_class_inflate_generic_type (MonoType *type, MonoGenericContext *context)
{
- MonoType *inflated = NULL;
-
- if (context)
- inflated = inflate_generic_type (type, context);
-
- if (!inflated)
- return mono_metadata_type_dup (NULL, type);
-
- mono_stats.inflated_type_count++;
- return inflated;
+ return mono_class_inflate_generic_type_with_mempool (NULL, type, context);
}
+
static MonoGenericContext
inflate_generic_context (MonoGenericContext *context, MonoGenericContext *inflate_with)
{
result->klass = klass_hint;
if (!result->klass) {
- MonoType *inflated = inflate_generic_type (&method->klass->byval_arg, context);
+ MonoType *inflated = inflate_generic_type (NULL, &method->klass->byval_arg, context);
result->klass = inflated ? mono_class_from_mono_type (inflated) : method->klass;
if (inflated)
mono_metadata_free_type (inflated);
if (!ftype)
return NULL;
if (class->generic_class) {
+ //FIXME do we leak here?
ftype = mono_class_inflate_generic_type (ftype, mono_class_get_context (class));
ftype->attrs = cols [MONO_FIELD_FLAGS];
}
ifield->generic_type = gfield->type;
field->name = gfield->name;
field->generic_info = ifield;
- field->type = mono_class_inflate_generic_type (gfield->type, mono_class_get_context (class));
+ /*This memory must come from the image mempool as we don't have a change 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))
continue;
if (!t)
return NULL;
if (context && (context->class_inst || context->method_inst)) {
- MonoType *inflated = inflate_generic_type (t, context);
+ MonoType *inflated = inflate_generic_type (NULL, t, context);
if (inflated) {
t = inflated;
*did_inflate = TRUE;