*
* Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
* Copyright 2004-2009 Novell, Inc (http://www.novell.com)
+ * Copyright 2011 Rodrigo Kumpera
*
*/
#include <config.h>
#include <mono/utils/mono-string.h>
#include <mono/utils/mono-error-internals.h>
-
-#if HAVE_SGEN_GC
-static void* reflection_info_desc = NULL;
-#define MOVING_GC_REGISTER(addr) do { \
- if (!reflection_info_desc) { \
- gsize bmap = 1; \
- reflection_info_desc = mono_gc_make_descr_from_bitmap (&bmap, 1); \
- } \
- mono_gc_register_root ((char*)(addr), sizeof (gpointer), reflection_info_desc); \
- } while (0)
-#else
-#define MOVING_GC_REGISTER(addr)
-#endif
-
static gboolean is_usertype (MonoReflectionType *ref);
static MonoReflectionType *mono_reflection_type_resolve_user_types (MonoReflectionType *type);
if (!res)
return NULL;
- return g_memdup (res, MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * res->num_attrs);
+ res = g_memdup (res, MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * res->num_attrs);
+ res->cached = 0;
+ return res;
}
static gboolean
entry = g_new0 (GenericParamTableEntry, 1);
entry->owner = owner;
/* FIXME: track where gen_params should be freed and remove the GC root as well */
- MOVING_GC_REGISTER (&entry->gparam);
+ MONO_GC_REGISTER_ROOT_IF_MOVING (entry->gparam);
entry->gparam = gparam;
g_ptr_array_add (assembly->gen_params, entry);
if (token)
return token;
- g_assert (tb->generic_params);
-
reflection_methodbuilder_from_ctor_builder (&rmb, mb);
- parent = create_generic_typespec (assembly, tb);
+ if (tb->generic_params)
+ parent = create_generic_typespec (assembly, tb);
+ else
+ parent = mono_image_typedef_or_ref (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)tb));
+
name = mono_string_to_utf8 (rmb.name);
sig = method_builder_encode_signature (assembly, &rmb);
if (is_field_on_inst (field))
type = get_field_on_inst_generic_type (field);
else
- type = field->type;
+ type = mono_field_get_type (field);
}
token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
mono_field_get_name (field),
MonoMethod *method, *inflated;
int count, i;
+ init_type_builder_generics ((MonoObject*)m->inst);
+
method = inflate_method (m->inst, (MonoObject*)m->mb);
klass = method->klass;
ctor = mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token));
g_assert (ctor);
- if (!strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
+ if (!strcmp (ctor->vtable->klass->name, "MonoCMethod")|| !strcmp (ctor->vtable->klass->name, "ConstructorBuilder")) {
MonoMethod *m = ((MonoReflectionMethod*)ctor)->method;
idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, m));
values [MONO_CUSTOM_ATTR_TYPE] = (idx << MONO_CUSTOM_ATTR_TYPE_BITS) | MONO_CUSTOM_ATTR_TYPE_METHODDEF;
if (tb->generic_params) {
token = mono_image_get_generic_field_token (assembly, fb);
} else {
- if ((tb->module->dynamic_image == assembly)) {
+ if (tb->module->dynamic_image == assembly) {
token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
} else {
token = mono_image_get_fieldref_token (assembly, (MonoObject*)fb, fb->handle);
type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
token = mono_image_typedef_or_ref_full (assembly, type, TRUE);
token = mono_metadata_token_from_dor (token);
- } else {
+ } else if (tb->module->dynamic_image == assembly) {
token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
+ } else {
+ MonoType *type;
+ type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
+ token = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, type));
}
} else if (strcmp (klass->name, "MonoType") == 0) {
MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
MonoClass *mc = mono_class_from_mono_type (type);
- if (!mono_class_init (mc))
- mono_raise_exception (mono_class_get_exception_for_failure (mc));
-
token = mono_metadata_token_from_dor (
mono_image_typedef_or_ref_full (assembly, type, mc->generic_container == NULL || create_open_instance));
} else if (strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
if (di->gen_params) {
for (i = 0; i < di->gen_params->len; i++) {
GenericParamTableEntry *entry = g_ptr_array_index (di->gen_params, i);
- if (entry->gparam->type.type) {
- MonoGenericParam *param = entry->gparam->type.type->data.generic_param;
- g_free ((char*)mono_generic_param_info (param)->name);
- g_free (param);
- }
mono_gc_deregister_root ((char*) &entry->gparam);
g_free (entry);
}
return res;
}
-static gboolean
-mymono_metadata_type_equal (MonoType *t1, MonoType *t2)
-{
- if ((t1->type != t2->type) ||
- (t1->byref != t2->byref))
- return FALSE;
-
- switch (t1->type) {
- case MONO_TYPE_VOID:
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_CHAR:
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- case MONO_TYPE_R4:
- case MONO_TYPE_R8:
- case MONO_TYPE_STRING:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_TYPEDBYREF:
- return TRUE;
- case MONO_TYPE_VALUETYPE:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_SZARRAY:
- return t1->data.klass == t2->data.klass;
- case MONO_TYPE_PTR:
- return mymono_metadata_type_equal (t1->data.type, t2->data.type);
- case MONO_TYPE_ARRAY:
- if (t1->data.array->rank != t2->data.array->rank)
- return FALSE;
- return t1->data.array->eklass == t2->data.array->eklass;
- case MONO_TYPE_GENERICINST: {
- int i;
- MonoGenericInst *i1 = t1->data.generic_class->context.class_inst;
- MonoGenericInst *i2 = t2->data.generic_class->context.class_inst;
- if (i1->type_argc != i2->type_argc)
- return FALSE;
- if (!mono_metadata_type_equal (&t1->data.generic_class->container_class->byval_arg,
- &t2->data.generic_class->container_class->byval_arg))
- return FALSE;
- /* FIXME: we should probably just compare the instance pointers directly. */
- for (i = 0; i < i1->type_argc; ++i) {
- if (!mono_metadata_type_equal (i1->type_argv [i], i2->type_argv [i]))
- return FALSE;
- }
- return TRUE;
- }
- case MONO_TYPE_VAR:
- case MONO_TYPE_MVAR:
- return t1->data.generic_param == t2->data.generic_param;
- default:
- g_error ("implement type compare for %0x!", t1->type);
- return FALSE;
- }
-
- return FALSE;
-}
-
-static guint
-mymono_metadata_type_hash (MonoType *t1)
-{
- guint hash;
-
- hash = t1->type;
-
- hash |= t1->byref << 6; /* do not collide with t1->type values */
- switch (t1->type) {
- case MONO_TYPE_VALUETYPE:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_SZARRAY:
- /* check if the distribution is good enough */
- return ((hash << 5) - hash) ^ mono_aligned_addr_hash (t1->data.klass);
- case MONO_TYPE_PTR:
- return ((hash << 5) - hash) ^ mymono_metadata_type_hash (t1->data.type);
- case MONO_TYPE_GENERICINST: {
- int i;
- MonoGenericInst *inst = t1->data.generic_class->context.class_inst;
- hash += g_str_hash (t1->data.generic_class->container_class->name);
- hash *= 13;
- for (i = 0; i < inst->type_argc; ++i) {
- hash += mymono_metadata_type_hash (inst->type_argv [i]);
- hash *= 13;
- }
- return hash;
- }
- case MONO_TYPE_VAR:
- case MONO_TYPE_MVAR:
- return ((hash << 5) - hash) ^ GPOINTER_TO_UINT (t1->data.generic_param);
- }
- return hash;
-}
-
static gboolean
verify_safe_for_managed_space (MonoType *type)
{
mono_loader_lock (); /*FIXME mono_class_init and mono_class_vtable acquire it*/
mono_domain_lock (domain);
if (!domain->type_hash)
- domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mymono_metadata_type_hash,
- (GCompareFunc)mymono_metadata_type_equal, MONO_HASH_VALUE_GC);
+ domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash,
+ (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC);
if ((res = mono_g_hash_table_lookup (domain->type_hash, type))) {
mono_domain_unlock (domain);
mono_loader_unlock ();
return mono_class_get_ref_info (klass);
}
}
-#ifdef HAVE_SGEN_GC
- res = (MonoReflectionType *)mono_gc_alloc_pinned_obj (mono_class_vtable (domain, mono_defaults.monotype_class), mono_class_instance_size (mono_defaults.monotype_class));
-#else
- res = (MonoReflectionType *)mono_object_new (domain, mono_defaults.monotype_class);
-#endif
+ /* This is stored in vtables/JITted code so it has to be pinned */
+ res = (MonoReflectionType *)mono_object_new_pinned (domain, mono_defaults.monotype_class);
res->type = type;
mono_g_hash_table_insert (domain->type_hash, type, res);
unsigned char format, flags;
int i;
+ /* for compatibility with .net */
+ if (method->dynamic)
+ mono_raise_exception (mono_get_exception_invalid_operation (NULL));
+
if (!System_Reflection_MethodBody)
System_Reflection_MethodBody = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MethodBody");
if (!System_Reflection_LocalVariableInfo)
int etype = *p;
p ++;
- if (etype == 0x51)
- /* See Partition II, Appendix B3 */
- etype = MONO_TYPE_OBJECT;
type = MONO_TYPE_SZARRAY;
- simple_type.type = etype;
- tklass = mono_class_from_mono_type (&simple_type);
+ if (etype == 0x50) {
+ tklass = mono_defaults.systemtype_class;
+ } else {
+ if (etype == 0x51)
+ /* See Partition II, Appendix B3 */
+ etype = MONO_TYPE_OBJECT;
+ simple_type.type = etype;
+ tklass = mono_class_from_mono_type (&simple_type);
+ }
goto handle_enum;
} else if (subt == 0x55) {
char *n;
val = load_cattr_value (image, &subc->byval_arg, p, end);
obj = mono_object_new (mono_domain_get (), subc);
g_assert (!subc->has_references);
- memcpy ((char*)obj + sizeof (MonoObject), val, mono_class_value_size (subc, NULL));
+ mono_gc_memmove ((char*)obj + sizeof (MonoObject), val, mono_class_value_size (subc, NULL));
g_free (val);
return obj;
}
}
static MonoObject*
-create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len)
+create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoError *error)
{
const char *p = (const char*)data;
const char *named;
void **params;
MonoMethodSignature *sig;
+ mono_error_init (error);
+
mono_class_init (method->klass);
- if (!mono_verifier_verify_cattr_content (image, method, data, len, NULL))
+ if (!mono_verifier_verify_cattr_content (image, method, data, len, NULL)) {
+ mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid.");
return NULL;
+ }
if (len == 0) {
attr = mono_object_new (mono_domain_get (), method->klass);
return attr;
}
-MonoArray*
-mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
-{
- MonoArray *result;
- MonoObject *attr;
- int i;
-
- result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, cinfo->num_attrs);
- for (i = 0; i < cinfo->num_attrs; ++i) {
- if (!cinfo->attrs [i].ctor)
- /* The cattr type is not finished yet */
- /* We should include the type name but cinfo doesn't contain it */
- mono_raise_exception (mono_get_exception_type_load (NULL, NULL));
- attr = create_custom_attr (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size);
- mono_array_setref (result, i, attr);
- }
- return result;
-}
-
static MonoArray*
-mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_klass)
+mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_klass, MonoError *error)
{
MonoArray *result;
MonoObject *attr;
int i, n;
+ mono_error_init (error);
+
n = 0;
for (i = 0; i < cinfo->num_attrs; ++i) {
- if (mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass))
+ if (!attr_klass || mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass))
n ++;
}
result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, n);
n = 0;
for (i = 0; i < cinfo->num_attrs; ++i) {
- if (mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass)) {
- attr = create_custom_attr (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size);
+ if (!cinfo->attrs [i].ctor)
+ /* The cattr type is not finished yet */
+ /* We should include the type name but cinfo doesn't contain it */
+ mono_raise_exception (mono_get_exception_type_load (NULL, NULL));
+ if (!attr_klass || mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass)) {
+ attr = create_custom_attr (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size, error);
+ if (!mono_error_ok (error))
+ return result;
mono_array_setref (result, n, attr);
n ++;
}
return result;
}
+MonoArray*
+mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
+{
+ MonoError error;
+
+ return mono_custom_attrs_construct_by_type (cinfo, NULL, &error);
+}
+
static MonoArray*
mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo)
{
* occurs.
*/
MonoArray*
-mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass)
+mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass, MonoError *error)
{
MonoArray *result;
MonoCustomAttrInfo *cinfo;
+ mono_error_init (error);
+
cinfo = mono_reflection_get_custom_attrs_info (obj);
if (cinfo) {
- if (attr_klass)
- result = mono_custom_attrs_construct_by_type (cinfo, attr_klass);
- else
- result = mono_custom_attrs_construct (cinfo);
+ result = mono_custom_attrs_construct_by_type (cinfo, attr_klass, error);
if (!cinfo->cached)
mono_custom_attrs_free (cinfo);
} else {
MonoArray*
mono_reflection_get_custom_attrs (MonoObject *obj)
{
- return mono_reflection_get_custom_attrs_by_type (obj, NULL);
+ MonoError error;
+
+ return mono_reflection_get_custom_attrs_by_type (obj, NULL, &error);
}
/*
mono_class_setup_supertypes (class);
} else {
if (!domain->type_hash)
- domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mymono_metadata_type_hash,
- (GCompareFunc)mymono_metadata_type_equal, MONO_HASH_VALUE_GC);
+ domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash,
+ (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC);
mono_g_hash_table_insert (domain->type_hash, res, type);
}
mono_domain_unlock (domain);
m->slot = -1;
m->flags = rmb->attrs;
m->iflags = rmb->iattrs;
- m->name = mono_string_to_utf8_image (image, rmb->name, &error);
- g_assert (mono_error_ok (&error));
+ m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
m->klass = klass;
m->signature = sig;
m->sre_method = TRUE;
{
MonoClassField *field;
MonoType *custom;
+ MonoError error;
field = g_new0 (MonoClassField, 1);
- field->name = mono_string_to_utf8 (fb->name);
+ field->name = mono_string_to_utf8_image (klass->image, fb->name, &error);
+ g_assert (mono_error_ok (&error));
if (fb->attrs || fb->modreq || fb->modopt) {
field->type = mono_metadata_type_dup (NULL, mono_reflection_type_get_handle ((MonoReflectionType*)fb->type));
field->type->attrs = fb->attrs;
g_assert (klass->image->dynamic);
custom = add_custom_modifiers ((MonoDynamicImage*)klass->image, field->type, fb->modreq, fb->modopt);
g_free (field->type);
- field->type = custom;
+ field->type = mono_metadata_type_dup (klass->image, custom);
+ g_free (custom);
} else {
field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type);
}
mono_g_hash_table_insert (image->generic_def_objects, imethod, rmethod);
mono_loader_unlock ();
}
+
+ if (!mono_verifier_is_method_valid_generic_instantiation (inflated))
+ mono_raise_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
return mono_method_get_object (mono_object_domain (rmethod), inflated, NULL);
}
gklass = gclass->container_class;
mono_class_init (gklass);
- dgclass->count_methods = methods ? mono_array_length (methods) : 0;
- dgclass->count_ctors = ctors ? mono_array_length (ctors) : 0;
dgclass->count_fields = fields ? mono_array_length (fields) : 0;
- dgclass->methods = g_new0 (MonoMethod *, dgclass->count_methods);
- dgclass->ctors = g_new0 (MonoMethod *, dgclass->count_ctors);
- dgclass->fields = g_new0 (MonoClassField, dgclass->count_fields);
- dgclass->field_objects = g_new0 (MonoObject*, dgclass->count_fields);
- dgclass->field_generic_types = g_new0 (MonoType*, dgclass->count_fields);
-
- for (i = 0; i < dgclass->count_methods; i++) {
- MonoObject *obj = mono_array_get (methods, gpointer, i);
-
- dgclass->methods [i] = inflate_method ((MonoReflectionType*)type, obj);
- }
-
- for (i = 0; i < dgclass->count_ctors; i++) {
- MonoObject *obj = mono_array_get (ctors, gpointer, i);
-
- dgclass->ctors [i] = inflate_method ((MonoReflectionType*)type, obj);
- }
+ dgclass->fields = mono_image_set_new0 (gclass->owner, MonoClassField, dgclass->count_fields);
+ dgclass->field_objects = mono_image_set_new0 (gclass->owner, MonoObject*, dgclass->count_fields);
+ dgclass->field_generic_types = mono_image_set_new0 (gclass->owner, MonoType*, dgclass->count_fields);
for (i = 0; i < dgclass->count_fields; i++) {
MonoObject *obj = mono_array_get (fields, gpointer, i);
dgclass->fields [i].type = mono_class_inflate_generic_type (
field->type, mono_generic_class_get_context ((MonoGenericClass *) dgclass));
dgclass->field_generic_types [i] = field->type;
- MOVING_GC_REGISTER (&dgclass->field_objects [i]);
+ MONO_GC_REGISTER_ROOT_IF_MOVING (dgclass->field_objects [i]);
dgclass->field_objects [i] = obj;
if (inflated_field) {
g_free (inflated_field);
} else {
- dgclass->fields [i].name = g_strdup (dgclass->fields [i].name);
+ dgclass->fields [i].name = mono_image_set_strdup (gclass->owner, dgclass->fields [i].name);
}
}
dgclass->initialized = TRUE;
}
+void
+mono_reflection_free_dynamic_generic_class (MonoGenericClass *gclass)
+{
+ MonoDynamicGenericClass *dgclass;
+ int i;
+
+ g_assert (gclass->is_dynamic);
+
+ dgclass = (MonoDynamicGenericClass *)gclass;
+
+ for (i = 0; i < dgclass->count_fields; ++i) {
+ MonoClassField *field = dgclass->fields + i;
+ mono_metadata_free_type (field->type);
+ MONO_GC_UNREGISTER_ROOT_IF_MOVING (dgclass->field_objects [i]);
+ }
+}
+
static void
fix_partial_generic_class (MonoClass *klass)
{
klass->size_inited = 1;
for (i = 0; i < klass->field.count; ++i) {
+ MonoArray *rva_data;
fb = mono_array_get (tb->fields, gpointer, i);
field = &klass->fields [i];
field->name = mono_string_to_utf8_image (image, fb->name, error);
} else {
field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type);
}
- if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && fb->rva_data)
- klass->ext->field_def_values [i].data = mono_array_addr (fb->rva_data, char, 0);
+
+ if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
+ char *base = mono_array_addr (rva_data, char, 0);
+ size_t size = mono_array_length (rva_data);
+ char *data = mono_image_alloc (klass->image, size);
+ memcpy (data, base, size);
+ klass->ext->field_def_values [i].data = data;
+ }
if (fb->offset != -1)
field->offset = fb->offset;
field->parent = klass;
klass->flags = tb->attrs;
klass->has_cctor = 1;
klass->has_finalize = 1;
+ klass->has_finalize_inited = 1;
/* fool mono_class_setup_parent */
klass->supertypes = NULL;
MonoGenericParamFull *param;
MonoImage *image;
MonoClass *pklass;
+ MonoError error;
MONO_ARCH_SAVE_REGS;
- param = g_new0 (MonoGenericParamFull, 1);
+ image = &gparam->tbuilder->module->dynamic_image->image;
+
+ param = mono_image_new0 (image, MonoGenericParamFull, 1);
+
+ param->info.name = mono_string_to_utf8_image (image, gparam->name, &error);
+ g_assert (mono_error_ok (&error));
+ param->param.num = gparam->index;
if (gparam->mbuilder) {
if (!gparam->mbuilder->generic_container) {
param->param.owner = gparam->tbuilder->generic_container;
}
- param->info.name = mono_string_to_utf8 (gparam->name);
- param->param.num = gparam->index;
-
- image = &gparam->tbuilder->module->dynamic_image->image;
pklass = mono_class_from_generic_parameter ((MonoGenericParam *) param, image, gparam->mbuilder != NULL);
gparam->type.type = &pklass->byval_arg;
return result;
}
+typedef struct {
+ MonoMethod *handle;
+ MonoDomain *domain;
+} DynamicMethodReleaseData;
+
+/*
+ * The runtime automatically clean up those after finalization.
+*/
+static MonoReferenceQueue *dynamic_method_queue;
+
+static void
+free_dynamic_method (void *dynamic_method)
+{
+ DynamicMethodReleaseData *data = dynamic_method;
+
+ mono_runtime_free_method (data->domain, data->handle);
+ g_free (data);
+}
+
void
mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
{
+ MonoReferenceQueue *queue;
+ MonoMethod *handle;
+ DynamicMethodReleaseData *release_data;
ReflectionMethodBuilder rmb;
MonoMethodSignature *sig;
MonoClass *klass;
GSList *l;
int i;
+ if (mono_runtime_is_shutting_down ())
+ mono_raise_exception (mono_get_exception_invalid_operation (""));
+
+ if (!(queue = dynamic_method_queue)) {
+ mono_loader_lock ();
+ if (!(queue = dynamic_method_queue))
+ queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
+ mono_loader_unlock ();
+ }
+
sig = dynamic_method_to_signature (mb);
reflection_methodbuilder_from_dynamic_method (&rmb, mb);
klass = mb->owner ? mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner)) : mono_defaults.object_class;
- mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig);
+ mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig);
+ release_data = g_new (DynamicMethodReleaseData, 1);
+ release_data->handle = handle;
+ release_data->domain = mono_object_get_domain ((MonoObject*)mb);
+ if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
+ g_free (release_data);
/* Fix up refs entries pointing at us */
for (l = mb->referenced_by; l; l = l->next) {
#endif /* DISABLE_REFLECTION_EMIT */
-void
-mono_reflection_destroy_dynamic_method (MonoReflectionDynamicMethod *mb)
-{
- g_assert (mb);
-
- if (mb->mhandle)
- mono_runtime_free_method (
- mono_object_get_domain ((MonoObject*)mb), mb->mhandle);
-}
-
/**
*
* mono_reflection_is_valid_dynamic_token:
return ref->type;
}
+void
+mono_reflection_free_dynamic_generic_class (MonoGenericClass *gclass)
+{
+ g_assert_not_reached ();
+}
+
#endif /* DISABLE_REFLECTION_EMIT */
/* SECURITY_ACTION_* are defined in mono/metadata/tabledefs.h */
else
return *(MonoBoolean*)mono_object_unbox (res);
}
+
+/**
+ * mono_reflection_type_get_type:
+ * @reftype: the System.Type object
+ *
+ * Returns the MonoType* associated with the C# System.Type object @reftype.
+ */
+MonoType*
+mono_reflection_type_get_type (MonoReflectionType *reftype)
+{
+ g_assert (reftype);
+
+ return mono_reflection_type_get_handle (reftype);
+}
+