*
* 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>
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
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);
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 (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);
}
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;
}
}
#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:
/*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;
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);
- g_assert (mb->mhandle);
+ (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m);
+ (*overrides) [onum * 2 + 1] = mb->mhandle;
- onum ++;
+ g_assert (mb->mhandle);
+
+ 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;
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);
+}
+