*
* 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
switch (mono_metadata_token_table (token)) {
case MONO_TABLE_METHOD:
type |= MONO_CUSTOM_ATTR_TYPE_METHODDEF;
+ /*
+ * fixup_cattrs () needs to fix this up. We can't use image->tokens, since it contains the old token for the
+ * method, not the one returned by mono_image_create_token ().
+ */
+ mono_g_hash_table_insert (assembly->remapped_tokens, GUINT_TO_POINTER (token), cattr->ctor);
break;
case MONO_TABLE_MEMBERREF:
type |= MONO_CUSTOM_ATTR_TYPE_MEMBERREF;
MonoDynamicTable *table;
guint32 *values;
guint32 tok;
+ MonoReflectionMethod *m;
+ int i;
- if (!mb->override_method)
+ if (!mb->override_methods)
return;
- table = &assembly->tables [MONO_TABLE_METHODIMPL];
- table->rows ++;
- alloc_table (table, table->rows);
- values = table->values + table->rows * MONO_METHODIMPL_SIZE;
- values [MONO_METHODIMPL_CLASS] = tb->table_idx;
- values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS);
+ for (i = 0; i < mono_array_length (mb->override_methods); ++i) {
+ m = mono_array_get (mb->override_methods, MonoReflectionMethod*, i);
- tok = mono_image_create_token (assembly, (MonoObject*)mb->override_method, FALSE, FALSE);
- switch (mono_metadata_token_table (tok)) {
- case MONO_TABLE_MEMBERREF:
- tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF;
- break;
- case MONO_TABLE_METHOD:
- tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODDEF;
- break;
- default:
- g_assert_not_reached ();
+ table = &assembly->tables [MONO_TABLE_METHODIMPL];
+ table->rows ++;
+ alloc_table (table, table->rows);
+ values = table->values + table->rows * MONO_METHODIMPL_SIZE;
+ values [MONO_METHODIMPL_CLASS] = tb->table_idx;
+ values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS);
+
+ tok = mono_image_create_token (assembly, (MonoObject*)m, FALSE, FALSE);
+ switch (mono_metadata_token_table (tok)) {
+ case MONO_TABLE_MEMBERREF:
+ tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF;
+ break;
+ case MONO_TABLE_METHOD:
+ tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODDEF;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ values [MONO_METHODIMPL_DECLARATION] = tok;
}
- values [MONO_METHODIMPL_DECLARATION] = tok;
}
#ifndef DISABLE_REFLECTION_EMIT
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),
if ((type & MONO_CUSTOM_ATTR_TYPE_MASK) == MONO_CUSTOM_ATTR_TYPE_METHODDEF) {
idx = type >> MONO_CUSTOM_ATTR_TYPE_BITS;
token = mono_metadata_make_token (MONO_TABLE_METHOD, idx);
- ctor = mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token));
+ ctor = mono_g_hash_table_lookup (assembly->remapped_tokens, GUINT_TO_POINTER (token));
g_assert (ctor);
if (!strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
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;
+ } else if (!strcmp (ctor->vtable->klass->name, "ConstructorBuilder")) {
+ MonoMethod *m = ((MonoReflectionCtorBuilder*)ctor)->mhandle;
+ 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) {
image->typeref = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
image->blob_cache = g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal);
image->gen_params = g_ptr_array_new ();
+ image->remapped_tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
/*g_print ("string heap create for image %p (%s)\n", image, module_name);*/
string_heap_init (&image->sheap);
g_free (key);
}
+static void
+release_hashtable (MonoGHashTable **hash)
+{
+ if (*hash) {
+ mono_g_hash_table_destroy (*hash);
+ *hash = NULL;
+ }
+}
+
+void
+mono_dynamic_image_release_gc_roots (MonoDynamicImage *image)
+{
+ release_hashtable (&image->token_fixups);
+ release_hashtable (&image->handleref_managed);
+ release_hashtable (&image->tokens);
+ release_hashtable (&image->remapped_tokens);
+ release_hashtable (&image->generic_def_objects);
+ release_hashtable (&image->methodspec);
+}
+
void
mono_dynamic_image_free (MonoDynamicImage *image)
{
mono_g_hash_table_destroy (di->handleref_managed);
if (di->tokens)
mono_g_hash_table_destroy (di->tokens);
+ if (di->remapped_tokens)
+ mono_g_hash_table_destroy (di->remapped_tokens);
if (di->generic_def_objects)
mono_g_hash_table_destroy (di->generic_def_objects);
if (di->blob_cache) {
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);
}
if (mspecs [i + 1])
- MONO_OBJECT_SETREF (param, MarshalAsImpl, (MonoObject*)mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [i + 1]));
+ MONO_OBJECT_SETREF (param, MarshalAsImpl, (MonoObject*)mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [i + 1]));
mono_array_setref (res, i, param);
}
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;
}
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);
}
#endif /* !DISABLE_REFLECTION_EMIT */
-MonoReflectionMarshal*
-mono_reflection_marshal_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
+MonoReflectionMarshalAsAttribute*
+mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
MonoMarshalSpec *spec)
{
- static MonoClass *System_Reflection_Emit_UnmanagedMarshalClass;
- MonoReflectionMarshal *minfo;
+ static MonoClass *System_Reflection_Emit_MarshalAsAttribute;
+ MonoReflectionMarshalAsAttribute *minfo;
MonoType *mtype;
- if (!System_Reflection_Emit_UnmanagedMarshalClass) {
- System_Reflection_Emit_UnmanagedMarshalClass = mono_class_from_name (
- mono_defaults.corlib, "System.Reflection.Emit", "UnmanagedMarshal");
- g_assert (System_Reflection_Emit_UnmanagedMarshalClass);
+ if (!System_Reflection_Emit_MarshalAsAttribute) {
+ System_Reflection_Emit_MarshalAsAttribute = mono_class_from_name (
+ mono_defaults.corlib, "System.Runtime.InteropServices", "MarshalAsAttribute");
+ g_assert (System_Reflection_Emit_MarshalAsAttribute);
}
- minfo = (MonoReflectionMarshal*)mono_object_new (domain, System_Reflection_Emit_UnmanagedMarshalClass);
- minfo->type = spec->native;
+ minfo = (MonoReflectionMarshalAsAttribute*)mono_object_new (domain, System_Reflection_Emit_MarshalAsAttribute);
+ minfo->utype = spec->native;
- switch (minfo->type) {
+ switch (minfo->utype) {
case MONO_NATIVE_LPARRAY:
- minfo->eltype = spec->data.array_data.elem_type;
- minfo->count = spec->data.array_data.num_elem;
- minfo->param_num = spec->data.array_data.param_num;
+ minfo->array_subtype = spec->data.array_data.elem_type;
+ minfo->size_const = spec->data.array_data.num_elem;
+ if (spec->data.array_data.param_num != -1)
+ minfo->size_param_index = spec->data.array_data.param_num;
break;
case MONO_NATIVE_BYVALTSTR:
case MONO_NATIVE_BYVALARRAY:
- minfo->count = spec->data.array_data.num_elem;
+ minfo->size_const = spec->data.array_data.num_elem;
break;
case MONO_NATIVE_CUSTOM:
if (spec->data.custom_data.custom_name) {
mtype = mono_reflection_type_from_name (spec->data.custom_data.custom_name, klass->image);
if (mtype)
- MONO_OBJECT_SETREF (minfo, marshaltyperef, mono_type_get_object (domain, mtype));
+ MONO_OBJECT_SETREF (minfo, marshal_type_ref, mono_type_get_object (domain, mtype));
- MONO_OBJECT_SETREF (minfo, marshaltype, mono_string_new (domain, spec->data.custom_data.custom_name));
+ MONO_OBJECT_SETREF (minfo, marshal_type, mono_string_new (domain, spec->data.custom_data.custom_name));
}
if (spec->data.custom_data.cookie)
- MONO_OBJECT_SETREF (minfo, mcookie, mono_string_new (domain, spec->data.custom_data.cookie));
+ MONO_OBJECT_SETREF (minfo, marshal_cookie, mono_string_new (domain, spec->data.custom_data.cookie));
break;
default:
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);
}
/*TODO avoid saving custom attrs for generic classes as it's enough to have them on the generic type definition.*/
void
-mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *methods,
- MonoArray *ctors, MonoArray *fields, MonoArray *properties,
- MonoArray *events)
+mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
{
MonoGenericClass *gclass;
MonoDynamicGenericClass *dgclass;
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 = mono_image_set_new0 (gclass->owner, MonoMethod *, dgclass->count_methods);
- dgclass->ctors = mono_image_set_new0 (gclass->owner, MonoMethod *, dgclass->count_ctors);
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_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);
- }
-
for (i = 0; i < dgclass->count_fields; i++) {
MonoObject *obj = mono_array_get (fields, gpointer, i);
MonoClassField *field, *inflated_field = NULL;
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) {
for (i = 0; i < dgclass->count_fields; ++i) {
MonoClassField *field = dgclass->fields + i;
mono_metadata_free_type (field->type);
-#if HAVE_SGEN_GC
- MONO_GC_UNREGISTER_ROOT (dgclass->field_objects [i]);
-#endif
+ MONO_GC_UNREGISTER_ROOT_IF_MOVING (dgclass->field_objects [i]);
}
}
mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides)
{
MonoReflectionTypeBuilder *tb;
- int i, onum;
+ int i, j, onum;
+ MonoReflectionMethod *m;
*overrides = NULL;
*num_overrides = 0;
for (i = 0; i < tb->num_methods; ++i) {
MonoReflectionMethodBuilder *mb =
mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
- if (mb->override_method)
- onum ++;
+ if (mb->override_methods)
+ onum += mono_array_length (mb->override_methods);
}
}
for (i = 0; i < tb->num_methods; ++i) {
MonoReflectionMethodBuilder *mb =
mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
- if (mb->override_method) {
- (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject *)mb->override_method);
- (*overrides) [onum * 2 + 1] = mb->mhandle;
+ if (mb->override_methods) {
+ for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
+ m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
+
+ (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m);
+ (*overrides) [onum * 2 + 1] = mb->mhandle;
- g_assert (mb->mhandle);
+ g_assert (mb->mhandle);
- onum ++;
+ onum ++;
+ }
}
}
}
mono_error_init (error);
if (tb->class_size) {
- g_assert ((tb->packing_size & 0xfffffff0) == 0);
+ if ((tb->packing_size & 0xfffffff0) != 0) {
+ char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 16", klass->name, tb->packing_size);
+ mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+ return;
+ }
klass->packing_size = tb->packing_size;
real_size = klass->instance_size + tb->class_size;
}
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:
is_sre_pointer (mono_object_get_class(obj))) {
MonoReflectionType *ref_type = (MonoReflectionType *)obj;
MonoType *type = mono_reflection_type_get_handle (ref_type);
- result = mono_class_from_mono_type (type);
+
+ if (context) {
+ MonoType *inflated = mono_class_inflate_generic_type (type, context);
+ result = mono_class_from_mono_type (inflated);
+ mono_metadata_free_type (inflated);
+ } else {
+ result = mono_class_from_mono_type (type);
+ }
*handle_class = mono_defaults.typehandle_class;
} else {
g_print ("%s\n", obj->vtable->klass->name);
}
void
-mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *methods,
- MonoArray *ctors, MonoArray *fields, MonoArray *properties,
- MonoArray *events)
+mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
{
g_assert_not_reached ();
}
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);
+}
+