#include <mono/metadata/mempool-internals.h>
#include <mono/metadata/security-core-clr.h>
#include <mono/metadata/debug-helpers.h>
+#include <mono/metadata/verify-internals.h>
+#include <mono/metadata/mono-ptr-array.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);
#ifndef DISABLE_REFLECTION_EMIT
static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
-static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec);
+static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_open_instance);
static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *cb);
static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper);
static void ensure_runtime_vtable (MonoClass *klass);
static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
static MonoMethod * inflate_method (MonoReflectionType *type, MonoObject *obj);
+static guint32 create_typespec (MonoDynamicImage *assembly, MonoType *type);
+static void init_type_builder_generics (MonoObject *type);
+
#define RESOLVE_TYPE(type) do { type = (void*)mono_reflection_type_resolve_user_types ((MonoReflectionType*)type); } while (0)
#define RESOLVE_ARRAY_TYPE_ELEMENT(array, index) do { \
MonoReflectionType *__type = mono_array_get (array, MonoReflectionType*, index); \
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
{
SigBuffer buf;
guint32 idx;
+ guint32 typespec = 0;
+ MonoType *type;
+ MonoClass *class;
+
+ init_type_builder_generics (fb->type);
+
+ type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type);
+ class = mono_class_from_mono_type (type);
sigbuffer_init (&buf, 32);
sigbuffer_add_value (&buf, 0x06);
encode_custom_modifiers (assembly, fb->modreq, fb->modopt, &buf);
/* encode custom attributes before the type */
- encode_reflection_type (assembly, (MonoReflectionType*)fb->type, &buf);
+
+ if (class->generic_container)
+ typespec = create_typespec (assembly, type);
+
+ if (typespec) {
+ MonoGenericClass *gclass;
+ gclass = mono_metadata_lookup_generic_class (class, class->generic_container->context.class_inst, TRUE);
+ encode_generic_class (assembly, gclass, &buf);
+ } else {
+ encode_type (assembly, type, &buf);
+ }
idx = sigbuffer_add_to_blob_cached (assembly, &buf);
sigbuffer_free (&buf);
return idx;
#endif
#endif
break;
- case MONO_TYPE_VALUETYPE:
- if (val->vtable->klass->enumtype) {
- *ret_type = mono_class_enum_basetype (val->vtable->klass)->type;
+ case MONO_TYPE_VALUETYPE: {
+ MonoClass *klass = val->vtable->klass;
+
+ if (klass->enumtype) {
+ *ret_type = mono_class_enum_basetype (klass)->type;
goto handle_enum;
- } else
- g_error ("we can't encode valuetypes");
+ } else if (mono_is_corlib_image (klass->image) && strcmp (klass->name_space, "System") == 0 && strcmp (klass->name, "DateTime") == 0) {
+ len = 8;
+ } else
+ g_error ("we can't encode valuetypes, we should have never reached this line");
+ break;
+ }
case MONO_TYPE_CLASS:
break;
case MONO_TYPE_STRING: {
if (!mb && smb && smb->parameters)
nparams = mono_array_length (smb->parameters) - 1;
sigbuffer_init (&buf, 32);
- sigbuffer_add_byte (&buf, 0x08);
+ if (fb->call_conv & 0x20)
+ sigbuffer_add_byte (&buf, 0x28);
+ else
+ sigbuffer_add_byte (&buf, 0x08);
sigbuffer_add_value (&buf, nparams);
if (mb) {
encode_reflection_type (assembly, (MonoReflectionType*)mb->rtype, &buf);
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);
#ifndef DISABLE_REFLECTION_EMIT
static guint32
-mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoReflectionField *f)
+mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoClassField *field)
{
MonoType *type;
guint32 token;
- MonoClassField *field;
+
+ g_assert (field);
+ g_assert (field->parent);
token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
if (token)
return token;
- g_assert (f->field->parent);
- field = f->field;
if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) {
int index = field - field->parent->fields;
type = field->parent->generic_class->container_class->fields [index].type;
} else {
- if (is_field_on_inst (f->field))
- type = get_field_on_inst_generic_type (f->field);
+ if (is_field_on_inst (field))
+ type = get_field_on_inst_generic_type (field);
else
- type = f->field->type;
+ type = field->type;
}
- token = mono_image_get_memberref_token (assembly, &f->field->parent->byval_arg,
- mono_field_get_name (f->field),
+ token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
+ mono_field_get_name (field),
fieldref_encode_signature (assembly, field->parent->image, type));
mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
return token;
MonoMethod *method, *inflated;
int count, i;
+ init_type_builder_generics ((MonoObject*)m->inst);
+
method = inflate_method (m->inst, (MonoObject*)m->mb);
klass = method->klass;
return t;
}
+static void
+init_type_builder_generics (MonoObject *type)
+{
+ MonoReflectionTypeBuilder *tb;
+
+ if (!is_sre_type_builder(mono_object_class (type)))
+ return;
+ tb = (MonoReflectionTypeBuilder *)type;
+
+ if (tb && tb->generic_container)
+ mono_reflection_create_generic_class (tb);
+}
+
static guint32
mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb)
{
MonoDynamicTable *table;
MonoClass *klass;
- MonoType *custom = NULL;
+ MonoType *custom = NULL, *type;
guint32 *values;
guint32 token, pclass, parent, sig;
gchar *name;
klass = mono_class_from_mono_type (mono_reflection_type_get_handle (fb->typeb));
name = mono_string_to_utf8 (fb->name);
+ /*FIXME this is one more layer of ugliness due how types are created.*/
+ init_type_builder_generics (fb->type);
+
/* fb->type does not include the custom modifiers */
/* FIXME: We should do this in one place when a fieldbuilder is created */
- if (fb->modreq || fb->modopt) {
- custom = add_custom_modifiers (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)fb->type), fb->modreq, fb->modopt);
- sig = fieldref_encode_signature (assembly, NULL, custom);
- g_free (custom);
- } else {
- sig = fieldref_encode_signature (assembly, NULL, mono_reflection_type_get_handle ((MonoReflectionType*)fb->type));
- }
+ type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type);
+ if (fb->modreq || fb->modopt)
+ type = custom = add_custom_modifiers (assembly, type, fb->modreq, fb->modopt);
+
+ sig = fieldref_encode_signature (assembly, NULL, type);
+ g_free (custom);
parent = create_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb);
g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_TYPEDEFORREF_TYPESPEC);
#endif
static void
-collect_types (GPtrArray *types, MonoReflectionTypeBuilder *type)
+collect_types (MonoPtrArray *types, MonoReflectionTypeBuilder *type)
{
int i;
- g_ptr_array_add (types, type); /* FIXME: GC object added to unmanaged memory */
+ mono_ptr_array_append (*types, type);
if (!type->subtypes)
return;
MonoDynamicImage *assembly;
MonoReflectionAssemblyBuilder *assemblyb;
MonoDomain *domain;
- GPtrArray *types;
+ MonoPtrArray types;
guint32 *values;
int i, j;
mono_image_fill_module_table (domain, moduleb, assembly);
/* Collect all types into a list sorted by their table_idx */
- types = g_ptr_array_new ();
+ mono_ptr_array_init (types, moduleb->num_types);
if (moduleb->types)
for (i = 0; i < moduleb->num_types; ++i) {
MonoReflectionTypeBuilder *type = mono_array_get (moduleb->types, MonoReflectionTypeBuilder*, i);
- collect_types (types, type);
+ collect_types (&types, type);
}
- g_ptr_array_sort (types, (GCompareFunc)compare_types_by_table_idx);
+ mono_ptr_array_sort (types, (gpointer)compare_types_by_table_idx);
table = &assembly->tables [MONO_TABLE_TYPEDEF];
- table->rows += types->len;
+ table->rows += mono_ptr_array_size (types);
alloc_table (table, table->rows);
/*
* Emit type names + namespaces at one place inside the string heap,
* so load_class_names () needs to touch fewer pages.
*/
- for (i = 0; i < types->len; ++i) {
- MonoReflectionTypeBuilder *tb = g_ptr_array_index (types, i);
+ for (i = 0; i < mono_ptr_array_size (types); ++i) {
+ MonoReflectionTypeBuilder *tb = mono_ptr_array_get (types, i);
string_heap_insert_mstring (&assembly->sheap, tb->nspace);
}
- for (i = 0; i < types->len; ++i) {
- MonoReflectionTypeBuilder *tb = g_ptr_array_index (types, i);
+ for (i = 0; i < mono_ptr_array_size (types); ++i) {
+ MonoReflectionTypeBuilder *tb = mono_ptr_array_get (types, i);
string_heap_insert_mstring (&assembly->sheap, tb->name);
}
- for (i = 0; i < types->len; ++i) {
- MonoReflectionTypeBuilder *type = g_ptr_array_index (types, i);
+ for (i = 0; i < mono_ptr_array_size (types); ++i) {
+ MonoReflectionTypeBuilder *type = mono_ptr_array_get (types, i);
mono_image_get_type_info (domain, type, assembly);
}
}
}
- for (i = 0; i < types->len; ++i) {
- MonoReflectionTypeBuilder *type = g_ptr_array_index (types, i);
+ for (i = 0; i < mono_ptr_array_size (types); ++i) {
+ MonoReflectionTypeBuilder *type = mono_ptr_array_get (types, i);
if (type->methods) {
for (j = 0; j < type->num_methods; ++j) {
MonoReflectionMethodBuilder *mb = mono_array_get (
}
}
- g_ptr_array_free (types, TRUE);
+ mono_ptr_array_destroy (types);
fixup_cattrs (assembly);
}
{
MonoClass *klass;
guint32 token = 0;
+ MonoMethodSignature *sig;
klass = obj->vtable->klass;
if (strcmp (klass->name, "MonoMethod") == 0) {
MonoMethod *method = ((MonoReflectionMethod *)obj)->method;
- MonoMethodSignature *sig, *old;
+ MonoMethodSignature *old;
guint32 sig_token, parent;
int nargs, i;
} else if (strcmp (klass->name, "MethodBuilder") == 0) {
MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
ReflectionMethodBuilder rmb;
- guint32 parent, sig;
+ guint32 parent, sig_token;
+ int nopt_args, nparams, ngparams, i;
char *name;
reflection_methodbuilder_from_method_builder (&rmb, mb);
rmb.opt_types = opt_param_types;
+ nopt_args = mono_array_length (opt_param_types);
- sig = method_builder_encode_signature (assembly, &rmb);
+ nparams = rmb.parameters ? mono_array_length (rmb.parameters): 0;
+ ngparams = rmb.generic_params ? mono_array_length (rmb.generic_params): 0;
+ sig = mono_metadata_signature_alloc (&assembly->image, nparams + nopt_args);
+
+ sig->hasthis = !(rmb.attrs & METHOD_ATTRIBUTE_STATIC);
+ sig->explicit_this = (rmb.call_conv & 0x40) == 0x40;
+ sig->call_convention = rmb.call_conv;
+ sig->generic_param_count = ngparams;
+ sig->param_count = nparams + nopt_args;
+ sig->sentinelpos = nparams;
+ sig->ret = mono_reflection_type_get_handle (rmb.rtype);
+
+ for (i = 0; i < nparams; i++) {
+ MonoReflectionType *rt = mono_array_get (rmb.parameters, MonoReflectionType *, i);
+ sig->params [i] = mono_reflection_type_get_handle (rt);
+ }
+
+ for (i = 0; i < nopt_args; i++) {
+ MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
+ sig->params [nparams + i] = mono_reflection_type_get_handle (rt);
+ }
+
+ sig_token = method_builder_encode_signature (assembly, &rmb);
parent = mono_image_create_token (assembly, obj, TRUE, TRUE);
g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
name = mono_string_to_utf8 (rmb.name);
token = mono_image_get_varargs_method_token (
- assembly, parent, name, sig);
+ assembly, parent, name, sig_token);
g_free (name);
} else {
g_error ("requested method token for %s\n", klass->name);
}
+ g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
+ mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), obj);
return token;
}
*/
guint32
mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
- gboolean create_methodspec, gboolean register_token)
+ gboolean create_open_instance, gboolean register_token)
{
MonoClass *klass;
guint32 token = 0;
if (tb->module->dynamic_image == assembly && !tb->generic_params && !mb->generic_params)
token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
else
- token = mono_image_get_methodbuilder_token (assembly, mb, create_methodspec);
+ token = mono_image_get_methodbuilder_token (assembly, mb, create_open_instance);
/*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
} else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)obj;
if (tb->generic_params) {
token = mono_image_get_generic_field_token (assembly, fb);
} else {
- token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
+ 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);
+ }
}
} else if (strcmp (klass->name, "TypeBuilder") == 0) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
- token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
+ if (create_open_instance && tb->generic_params) {
+ MonoType *type;
+ init_type_builder_generics (obj);
+ 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 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);
token = mono_metadata_token_from_dor (
- mono_image_typedef_or_ref_full (assembly, type, mc->generic_container == NULL));
+ mono_image_typedef_or_ref_full (assembly, type, mc->generic_container == NULL || create_open_instance));
} else if (strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
token = mono_metadata_token_from_dor (
strcmp (klass->name, "MonoGenericCMethod") == 0) {
MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
if (m->method->is_inflated) {
- if (create_methodspec)
+ if (create_open_instance)
token = mono_image_get_methodspec_token (assembly, m->method);
else
token = mono_image_get_inflated_method_token (assembly, m->method);
token = MONO_TOKEN_METHOD_DEF | method_table_idx;
}
} else {
- token = mono_image_get_methodref_token (assembly, m->method, create_methodspec);
+ token = mono_image_get_methodref_token (assembly, m->method, create_open_instance);
}
/*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
} else if (strcmp (klass->name, "MonoField") == 0) {
field_table_idx --;
token = MONO_TOKEN_FIELD_DEF | field_table_idx;
} else {
- token = mono_image_get_fieldref_token (assembly, f);
+ token = mono_image_get_fieldref_token (assembly, (MonoObject*)f, f->field);
}
/*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
} else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
token = mono_image_get_field_on_inst_token (assembly, f);
} else if (strcmp (klass->name, "ConstructorOnTypeBuilderInst") == 0) {
MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
- token = mono_image_get_ctor_on_inst_token (assembly, c, create_methodspec);
+ token = mono_image_get_ctor_on_inst_token (assembly, c, create_open_instance);
} else if (strcmp (klass->name, "MethodOnTypeBuilderInst") == 0) {
MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
- token = mono_image_get_method_on_inst_token (assembly, m, create_methodspec);
+ token = mono_image_get_method_on_inst_token (assembly, m, create_open_instance);
} else if (is_sre_array (klass) || is_sre_byref (klass) || is_sre_pointer (klass)) {
MonoReflectionType *type = (MonoReflectionType *)obj;
token = mono_metadata_token_from_dor (
version = mono_get_runtime_info ()->runtime_version;
#if HAVE_BOEHM_GC
+ /* The MonoGHashTable's need GC tracking */
image = GC_MALLOC (sizeof (MonoDynamicImage));
#else
image = g_new0 (MonoDynamicImage, 1);
image->method_to_table_idx = g_hash_table_new (NULL, NULL);
image->field_to_table_idx = g_hash_table_new (NULL, NULL);
image->method_aux_hash = g_hash_table_new (NULL, NULL);
+ image->vararg_aux_hash = g_hash_table_new (NULL, NULL);
image->handleref = g_hash_table_new (NULL, NULL);
image->handleref_managed = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC);
image->tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
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);
}
g_hash_table_destroy (di->field_to_table_idx);
if (di->method_aux_hash)
g_hash_table_destroy (di->method_aux_hash);
+ if (di->vararg_aux_hash)
+ g_hash_table_destroy (di->vararg_aux_hash);
g_free (di->strong_name);
g_free (di->win32_res);
if (di->public_key)
return;
#if HAVE_BOEHM_GC
+ /* assembly->assembly.image might be GC allocated */
assembly = assemblyb->dynamic_assembly = GC_MALLOC (sizeof (MonoDynamicAssembly));
#else
assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
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) ^ g_str_hash (t1->data.klass->name);
- 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;
- }
- }
- return hash;
-}
-
-static MonoReflectionGenericClass*
-mono_generic_class_get_object (MonoDomain *domain, MonoType *geninst)
-{
- static MonoClass *System_Reflection_MonoGenericClass;
- MonoReflectionGenericClass *res;
- MonoClass *klass, *gklass;
- MonoGenericInst *ginst;
- MonoArray *type_args;
- int i;
- MonoObject *tb;
-
- g_assert (0); /*This code path should not be taken anymore, all MGC instantiation must happen in managed code*/
-
- if (!System_Reflection_MonoGenericClass) {
- System_Reflection_MonoGenericClass = mono_class_from_name (
- mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
- g_assert (System_Reflection_MonoGenericClass);
- }
-
- klass = mono_class_from_mono_type (geninst);
- gklass = klass->generic_class->container_class;
-
- mono_class_init (klass);
-
-#ifdef HAVE_SGEN_GC
- res = (MonoReflectionGenericClass *) mono_gc_alloc_pinned_obj (mono_class_vtable (domain, System_Reflection_MonoGenericClass), mono_class_instance_size (System_Reflection_MonoGenericClass));
-#else
- res = (MonoReflectionGenericClass *) mono_object_new (domain, System_Reflection_MonoGenericClass);
-#endif
-
- res->type.type = geninst;
- tb = mono_class_get_ref_info (gklass);
- g_assert (tb);
- g_assert (!strcmp (tb->vtable->klass->name, "TypeBuilder"));
- MONO_OBJECT_SETREF (res, generic_type, tb);
-
- ginst = klass->generic_class->context.class_inst;
- type_args = mono_array_new (domain, mono_defaults.systemtype_class, ginst->type_argc);
- for (i = 0; i < ginst->type_argc; ++i)
- mono_array_setref (type_args, i, mono_type_get_object (domain, ginst->type_argv [i]));
- MONO_OBJECT_SETREF (res, type_arguments, type_args);
-
- return res;
-}
-
static gboolean
verify_safe_for_managed_space (MonoType *type)
{
return TRUE;
}
+static MonoType*
+mono_type_normalize (MonoType *type)
+{
+ int i;
+ MonoGenericClass *gclass;
+ MonoGenericInst *ginst;
+ MonoClass *gtd;
+ MonoGenericContainer *gcontainer;
+ MonoType **argv = NULL;
+ gboolean is_denorm_gtd = TRUE, requires_rebind = FALSE;
+
+ if (type->type != MONO_TYPE_GENERICINST)
+ return type;
+
+ gclass = type->data.generic_class;
+ ginst = gclass->context.class_inst;
+ if (!ginst->is_open)
+ return type;
+
+ gtd = gclass->container_class;
+ gcontainer = gtd->generic_container;
+ argv = g_newa (MonoType*, ginst->type_argc);
+
+ for (i = 0; i < ginst->type_argc; ++i) {
+ MonoType *t = ginst->type_argv [i], *norm;
+ if (t->type != MONO_TYPE_VAR || t->data.generic_param->num != i || t->data.generic_param->owner != gcontainer)
+ is_denorm_gtd = FALSE;
+ norm = mono_type_normalize (t);
+ argv [i] = norm;
+ if (norm != t)
+ requires_rebind = TRUE;
+ }
+
+ if (is_denorm_gtd)
+ return type->byref == gtd->byval_arg.byref ? >d->byval_arg : >d->this_arg;
+
+ if (requires_rebind) {
+ MonoClass *klass = mono_class_bind_generic_parameters (gtd, ginst->type_argc, argv, gclass->is_dynamic);
+ return type->byref == klass->byval_arg.byref ? &klass->byval_arg : &klass->this_arg;
+ }
+
+ return type;
+}
/*
* mono_type_get_object:
* @domain: an app domain
MonoReflectionType*
mono_type_get_object (MonoDomain *domain, MonoType *type)
{
+ MonoType *norm_type;
MonoReflectionType *res;
MonoClass *klass = mono_class_from_mono_type (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 res;
}
- /* Create a MonoGenericClass object for instantiations of not finished TypeBuilders */
- if ((type->type == MONO_TYPE_GENERICINST) && type->data.generic_class->is_dynamic && !type->data.generic_class->container_class->wastypebuilder) {
- res = (MonoReflectionType *)mono_generic_class_get_object (domain, type);
+
+ /*Types must be normalized so a generic instance of the GTD get's the same inner type.
+ * For example in: Foo<A,B>; Bar<A> : Foo<A, Bar<A>>
+ * The second Bar will be encoded a generic instance of Bar with <A> as parameter.
+ * On all other places, Bar<A> will be encoded as the GTD itself. This is an implementation
+ * artifact of how generics are encoded and should be transparent to managed code so we
+ * need to weed out this diference when retrieving managed System.Type objects.
+ */
+ norm_type = mono_type_normalize (type);
+ if (norm_type != type) {
+ res = mono_type_get_object (domain, norm_type);
mono_g_hash_table_insert (domain->type_hash, type, res);
mono_domain_unlock (domain);
mono_loader_unlock ();
return res;
}
+ /* This MonoGenericClass hack is no longer necessary. Let's leave it here until we finish with the 2-stage type-builder setup.*/
+ if ((type->type == MONO_TYPE_GENERICINST) && type->data.generic_class->is_dynamic && !type->data.generic_class->container_class->wastypebuilder)
+ g_assert (0);
+
if (!verify_safe_for_managed_space (type)) {
mono_domain_unlock (domain);
mono_loader_unlock ();
return mono_class_get_ref_info (klass);
}
}
- // FIXME: Get rid of this, do it in the icalls for Type
- mono_class_init (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);
res->klass = klass;
res->field = field;
MONO_OBJECT_SETREF (res, name, mono_string_new (domain, mono_field_get_name (field)));
- if (is_field_on_inst (field))
+
+ if (is_field_on_inst (field)) {
res->attrs = get_field_on_inst_generic_type (field)->attrs;
- else
- res->attrs = field->type->attrs;
- MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type));
+ MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type));
+ } else {
+ if (field->type)
+ MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type));
+ res->attrs = mono_field_get_flags (field);
+ }
CACHE_OBJECT (MonoReflectionField *, field, res, klass);
}
{
static MonoClass *System_Reflection_ParameterInfo;
static MonoClass *System_Reflection_ParameterInfo_array;
+ MonoError error;
MonoArray *res = NULL;
MonoReflectionMethod *member = NULL;
MonoReflectionParameter *param = NULL;
mono_memory_barrier ();
System_Reflection_ParameterInfo_array = klass;
}
-
- if (!mono_method_signature (method)->param_count)
+
+ sig = mono_method_signature_checked (method, &error);
+ if (!mono_error_ok (&error))
+ mono_error_raise_exception (&error);
+
+ if (!sig->param_count)
return mono_array_new_specific (mono_class_vtable (domain, System_Reflection_ParameterInfo_array), 0);
/* Note: the cache is based on the address of the signature into the method
*/
CHECK_OBJECT (MonoArray*, &(method->signature), refclass);
- sig = mono_method_signature (method);
member = mono_method_get_object (domain, method, refclass);
names = g_new (char *, sig->param_count);
mono_method_get_param_names (method, (const char **) names);
static MonoClass *System_Reflection_ExceptionHandlingClause = NULL;
MonoReflectionMethodBody *ret;
MonoMethodHeader *header;
+ MonoImage *image;
guint32 method_rva, local_var_sig_token;
char *ptr;
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)
(method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
(method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME))
return NULL;
+
+ image = method->klass->image;
header = mono_method_get_header (method);
-
- /* Obtain local vars signature token */
- method_rva = mono_metadata_decode_row_col (&method->klass->image->tables [MONO_TABLE_METHOD], mono_metadata_token_index (method->token) - 1, MONO_METHOD_RVA);
- ptr = mono_image_rva_map (method->klass->image, method_rva);
- flags = *(const unsigned char *) ptr;
- format = flags & METHOD_HEADER_FORMAT_MASK;
- switch (format){
- case METHOD_HEADER_TINY_FORMAT:
- local_var_sig_token = 0;
- break;
- case METHOD_HEADER_FAT_FORMAT:
- ptr += 2;
- ptr += 2;
- ptr += 4;
- local_var_sig_token = read32 (ptr);
- break;
- default:
- g_assert_not_reached ();
- }
+
+ if (!image->dynamic) {
+ /* Obtain local vars signature token */
+ method_rva = mono_metadata_decode_row_col (&image->tables [MONO_TABLE_METHOD], mono_metadata_token_index (method->token) - 1, MONO_METHOD_RVA);
+ ptr = mono_image_rva_map (image, method_rva);
+ flags = *(const unsigned char *) ptr;
+ format = flags & METHOD_HEADER_FORMAT_MASK;
+ switch (format){
+ case METHOD_HEADER_TINY_FORMAT:
+ local_var_sig_token = 0;
+ break;
+ case METHOD_HEADER_FAT_FORMAT:
+ ptr += 2;
+ ptr += 2;
+ ptr += 4;
+ local_var_sig_token = read32 (ptr);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ } else
+ local_var_sig_token = 0; //FIXME
ret = (MonoReflectionMethodBody*)mono_object_new (domain, System_Reflection_MethodBody);
assembly_name_to_aname (MonoAssemblyName *assembly, char *p) {
int found_sep;
char *s;
+ gboolean quoted = FALSE;
memset (assembly, 0, sizeof (MonoAssemblyName));
- assembly->name = p;
assembly->culture = "";
memset (assembly->public_key_token, 0, MONO_PUBLIC_KEY_TOKEN_LENGTH);
- while (*p && (isalnum (*p) || *p == '.' || *p == '-' || *p == '_' || *p == '$' || *p == '@'))
+ if (*p == '"') {
+ quoted = TRUE;
+ p++;
+ }
+ assembly->name = p;
+ while (*p && (isalnum (*p) || *p == '.' || *p == '-' || *p == '_' || *p == '$' || *p == '@' || g_ascii_isspace (*p)))
p++;
- found_sep = 0;
- while (g_ascii_isspace (*p) || *p == ',') {
- *p++ = 0;
- found_sep = 1;
- continue;
- }
- /* failed */
- if (!found_sep)
+ if (quoted) {
+ if (*p != '"')
+ return 1;
+ *p = 0;
+ p++;
+ }
+ if (*p != ',')
return 1;
+ *p = 0;
+ /* Remove trailing whitespace */
+ s = p - 1;
+ while (*s && g_ascii_isspace (*s))
+ *s-- = 0;
+ p ++;
+ while (g_ascii_isspace (*p))
+ p++;
while (*p) {
if (*p == 'V' && g_ascii_strncasecmp (p, "Version=", 8) == 0) {
p += 8;
if (!_mono_reflection_parse_type (p, &p, TRUE, subinfo))
return 0;
- if (fqname) {
+ /*MS is lenient on [] delimited parameters that aren't fqn - and F# uses them.*/
+ if (fqname && (*p != ']')) {
char *aname;
if (*p != ',')
if (!*aname ||
!assembly_name_to_aname (&subinfo->assembly, aname))
return 0;
+ } else if (fqname && (*p == ']')) {
+ *p++ = 0;
}
if (i + 1 < arity) {
}
if (!klass)
return NULL;
- mono_class_init (klass);
if (info->type_arguments) {
MonoType **type_args = g_new0 (MonoType *, info->type_arguments->len);
} else { /* array rank */
klass = mono_bounded_array_class_get (klass, modval, bounded);
}
- mono_class_init (klass);
}
return &klass->byval_arg;
} else if (strcmp (klass->name, "FieldBuilder") == 0) {
MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj;
- /* Call mono_image_create_token so the object gets added to the tokens hash table */
- token = mono_image_create_token (((MonoReflectionTypeBuilder*)fb->typeb)->module->dynamic_image, obj, FALSE, TRUE);
+ token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
} else if (strcmp (klass->name, "TypeBuilder") == 0) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
} else if (strcmp (klass->name, "MonoType") == 0) {
- MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
- token = mono_class_from_mono_type (type)->type_token;
+ 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 = mc->type_token;
} else if (strcmp (klass->name, "MonoCMethod") == 0 ||
strcmp (klass->name, "MonoMethod") == 0 ||
strcmp (klass->name, "MonoGenericMethod") == 0 ||
type = mono_class_enum_basetype (t->data.klass)->type;
goto handle_enum;
} else {
- g_error ("generic valutype %s not handled in custom attr value decoding", t->data.klass->name);
+ MonoClass *k = t->data.klass;
+
+ if (mono_is_corlib_image (k->image) && strcmp (k->name_space, "System") == 0 && strcmp (k->name, "DateTime") == 0){
+ guint64 *val = g_malloc (sizeof (guint64));
+ *val = read64 (p);
+ *end = p + 8;
+ return val;
+ }
}
+ g_error ("generic valutype %s not handled in custom attr value decoding", t->data.klass->name);
break;
+
case MONO_TYPE_STRING:
if (*p == (char)0xFF) {
*end = p + 1;
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;
}
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)) {
+ 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);
mono_runtime_invoke (method, attr, NULL, NULL);
guint32 i, j, num_named;
CattrNamedArg *arginfo = NULL;
+ if (!mono_verifier_verify_cattr_content (image, method, data, len, NULL))
+ return;
+
mono_class_init (method->klass);
*typed_args = NULL;
*named_args = namedargs;
}
-static MonoObject*
-create_custom_attr_data (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len)
+void
+mono_reflection_resolve_custom_attribute_data (MonoReflectionMethod *ref_method, MonoReflectionAssembly *assembly, gpointer data, guint32 len, MonoArray **ctor_args, MonoArray **named_args)
{
- MonoArray *typedargs, *namedargs;
- static MonoMethod *ctor;
MonoDomain *domain;
- MonoObject *attr;
- void *params [3];
+ MonoArray *typedargs, *namedargs;
+ MonoImage *image;
+ MonoMethod *method;
CattrNamedArg *arginfo;
int i;
- mono_class_init (method->klass);
+ *ctor_args = NULL;
+ *named_args = NULL;
- if (!ctor)
- ctor = mono_class_get_method_from_name (mono_defaults.customattribute_data_class, ".ctor", 3);
+ if (len == 0)
+ return;
- domain = mono_domain_get ();
- if (len == 0) {
- /* This is for Attributes with no parameters */
- attr = mono_object_new (domain, mono_defaults.customattribute_data_class);
- params [0] = mono_method_get_object (domain, method, NULL);
- params [1] = params [2] = NULL;
- mono_runtime_invoke (method, attr, params, NULL);
- return attr;
- }
+ image = assembly->assembly->image;
+ method = ref_method->method;
+ domain = mono_object_domain (ref_method);
+
+ if (!mono_class_init (method->klass))
+ mono_raise_exception (mono_class_get_exception_for_failure (method->klass));
mono_reflection_create_custom_attr_data_args (image, method, data, len, &typedargs, &namedargs, &arginfo);
+ if (mono_loader_get_last_error ())
+ mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
+
if (!typedargs || !namedargs)
- return NULL;
+ return;
for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
MonoObject *obj = mono_array_get (typedargs, MonoObject*, i);
mono_array_setref (namedargs, i, namedarg);
}
- attr = mono_object_new (domain, mono_defaults.customattribute_data_class);
- params [0] = mono_method_get_object (domain, method, NULL);
- params [1] = typedargs;
- params [2] = namedargs;
- mono_runtime_invoke (ctor, attr, params, NULL);
- return attr;
+ *ctor_args = typedargs;
+ *named_args = namedargs;
}
-MonoArray*
-mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
+static MonoObject*
+create_custom_attr_data (MonoImage *image, MonoCustomAttrEntry *cattr)
{
- MonoArray *result;
+ static MonoMethod *ctor;
+ MonoDomain *domain;
MonoObject *attr;
- int i;
+ void *params [4];
- 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;
+ g_assert (image->assembly);
+
+ if (!ctor)
+ ctor = mono_class_get_method_from_name (mono_defaults.customattribute_data_class, ".ctor", 4);
+
+ domain = mono_domain_get ();
+ attr = mono_object_new (domain, mono_defaults.customattribute_data_class);
+ params [0] = mono_method_get_object (domain, cattr->ctor, NULL);
+ params [1] = mono_assembly_get_object (domain, image->assembly);
+ params [2] = (gpointer)&cattr->data;
+ params [3] = &cattr->data_size;
+ mono_runtime_invoke (ctor, attr, params, NULL);
+ return attr;
}
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)
{
result = mono_array_new (mono_domain_get (), mono_defaults.customattribute_data_class, cinfo->num_attrs);
for (i = 0; i < cinfo->num_attrs; ++i) {
- attr = create_custom_attr_data (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size);
+ attr = create_custom_attr_data (cinfo->image, &cinfo->attrs [i]);
mono_array_setref (result, i, attr);
}
return result;
g_free (ainfo);
return NULL;
}
+
+ if (!mono_verifier_verify_cattr_blob (image, cols [MONO_CUSTOM_ATTR_VALUE], NULL)) {
+ /*FIXME raising an exception here doesn't make any sense*/
+ g_warning ("Invalid custom attribute blob on image %s for index %x", image->name, idx);
+ g_list_free (list);
+ g_free (ainfo);
+ return NULL;
+ }
data = mono_metadata_blob_heap (image, cols [MONO_CUSTOM_ATTR_VALUE]);
ainfo->attrs [i].data_size = mono_metadata_decode_value (data, &data);
ainfo->attrs [i].data = (guchar*)data;
image = method->klass->image;
method_index = mono_method_get_index (method);
+ if (!method_index)
+ return NULL;
ca = &image->tables [MONO_TABLE_METHOD];
param_list = mono_metadata_decode_row_col (ca, method_index - 1, MONO_METHOD_PARAMLIST);
if (klass == mono_defaults.monotype_class) {
MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
klass = mono_class_from_mono_type (type);
+ /*We cannot mono_class_init the class from which we'll load the custom attributes since this must work with broken types.*/
cinfo = mono_custom_attrs_from_class (klass);
} else if (strcmp ("Assembly", klass->name) == 0 || strcmp ("MonoAssembly", klass->name) == 0) {
MonoReflectionAssembly *rassembly = (MonoReflectionAssembly*)obj;
* 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);
return FALSE;
}
+static void
+init_type_builder_generics (MonoObject *type)
+{
+}
+
#endif /* !DISABLE_REFLECTION_EMIT */
(!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
klass->instance_size = sizeof (MonoObject);
klass->size_inited = 1;
- mono_class_setup_vtable_general (klass, NULL, 0);
+ mono_class_setup_vtable_general (klass, NULL, 0, NULL);
}
mono_class_setup_mono_type (klass);
* to create objects of the enum type (for use in SetConstant).
*/
/* FIXME: Does this mean enums can't have method overrides ? */
- mono_class_setup_vtable_general (klass, NULL, 0);
+ mono_class_setup_vtable_general (klass, NULL, 0, NULL);
}
mono_loader_unlock ();
}
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;
container->type_params [i] = *param;
}
+ /*
+ * The method signature might have pointers to generic parameters that belong to other methods.
+ * This is a valid SRE case, but the resulting method signature must be encoded using the proper
+ * generic parameters.
+ */
+ for (i = 0; i < m->signature->param_count; ++i) {
+ MonoType *t = m->signature->params [i];
+ if (t->type == MONO_TYPE_MVAR) {
+ MonoGenericParam *gparam = t->data.generic_param;
+ if (gparam->num < count) {
+ m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
+ m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
+ }
+
+ }
+ }
+
if (klass->generic_container) {
container->parent = klass->generic_container;
container->context.class_inst = klass->generic_container->context.class_inst;
{
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);
}
context = mono_class_get_context (klass);
- if (klass->method.count) {
+ if (klass->method.count && klass->methods) {
/* Find the already created inflated method */
for (i = 0; i < klass->method.count; ++i) {
g_assert (klass->methods [i]->is_inflated);
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);
+ 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->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)
{
return;
dgclass = (MonoDynamicGenericClass *) klass->generic_class;
+ if (klass->parent != gklass->parent) {
+ MonoError error;
+ MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, &error);
+ if (mono_error_ok (&error)) {
+ MonoClass *parent = mono_class_from_mono_type (parent_type);
+ mono_metadata_free_type (parent_type);
+ if (parent != klass->parent) {
+ /*fool mono_class_setup_parent*/
+ klass->supertypes = NULL;
+ mono_class_setup_parent (klass, parent);
+ }
+ } else {
+ mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_error_cleanup (&error);
+ if (gklass->wastypebuilder)
+ klass->wastypebuilder = TRUE;
+ return;
+ }
+ }
if (!dgclass->initialized)
return;
}
if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
- for (i = 0; i < klass->method.count; ++i)
- klass->methods [i]->slot = i;
+ int slot_num = 0;
+ for (i = 0; i < klass->method.count; ++i) {
+ MonoMethod *im = klass->methods [i];
+ if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
+ im->slot = slot_num++;
+ }
klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
mono_class_setup_interface_offsets (klass);
*/
}
+static MonoMethod*
+mono_reflection_method_get_handle (MonoObject *method)
+{
+ MonoClass *class = mono_object_class (method);
+ if (is_sr_mono_method (class) || is_sr_mono_generic_method (class)) {
+ MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
+ return sr_method->method;
+ }
+ if (is_sre_method_builder (class)) {
+ MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
+ return mb->mhandle;
+ }
+ if (is_sre_method_on_tb_inst (class)) {
+ MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)method;
+ MonoMethod *result;
+ /*FIXME move this to a proper method and unify with resolve_object*/
+ if (m->method_args) {
+ result = mono_reflection_method_on_tb_inst_get_handle (m);
+ } else {
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst);
+ MonoClass *inflated_klass = mono_class_from_mono_type (type);
+ MonoMethod *mono_method;
+
+ if (is_sre_method_builder (mono_object_class (m->mb)))
+ mono_method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
+ else if (is_sr_mono_method (mono_object_class (m->mb)))
+ mono_method = ((MonoReflectionMethod *)m->mb)->method;
+ else
+ g_error ("resolve_object:: can't handle a MTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (m->mb)));
+
+ result = inflate_mono_method (inflated_klass, mono_method, (MonoObject*)m->mb);
+ }
+ return result;
+ }
+
+ g_error ("Can't handle methods of type %s:%s", class->name_space, class->name);
+ return NULL;
+}
+
void
mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides)
{
MonoReflectionMethodBuilder *mb =
mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
if (mb->override_method) {
- (*overrides) [onum * 2] =
- mb->override_method->method;
- (*overrides) [onum * 2 + 1] =
- mb->mhandle;
+ (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject *)mb->override_method);
+ (*overrides) [onum * 2 + 1] = mb->mhandle;
- /* FIXME: What if 'override_method' is a MethodBuilder ? */
- g_assert (mb->override_method->method);
g_assert (mb->mhandle);
onum ++;
fb->handle = field;
mono_save_custom_attrs (klass->image, field, fb->cattrs);
+ if (klass->enumtype && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
+ klass->cast_class = klass->element_class = mono_class_from_mono_type (field->type);
+ }
if (fb->def_value) {
MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
properties [i].set = pb->set_method->mhandle;
mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
+ if (pb->def_value) {
+ guint32 len, idx;
+ const char *p, *p2;
+ MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
+ if (!klass->ext->prop_def_values)
+ klass->ext->prop_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->ext->property.count);
+ properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
+ idx = encode_constant (assembly, pb->def_value, &klass->ext->prop_def_values [i].def_type);
+ /* Copy the data from the blob since it might get realloc-ed */
+ p = assembly->blob.data + idx;
+ len = mono_metadata_decode_blob_size (p, &p2);
+ len += p2 - p;
+ klass->ext->prop_def_values [i].data = mono_image_alloc (image, len);
+ memcpy ((gpointer)klass->ext->prop_def_values [i].data, p, len);
+ }
}
}
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;
+ mono_class_setup_parent (klass, klass->parent);
+ mono_class_setup_mono_type (klass);
#if 0
if (!((MonoDynamicImage*)klass->image)->run) {
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 mono_g_hash_table_lookup (image->tokens, GUINT_TO_POINTER (token)) != NULL;
}
+MonoMethodSignature *
+mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token)
+{
+ MonoMethodSignature *sig;
+ g_assert (image->dynamic);
+
+ sig = g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
+ if (sig)
+ return sig;
+
+ return mono_method_signature (method);
+}
+
#ifndef DISABLE_REFLECTION_EMIT
/**
g_assert (result);
} else if (strcmp (obj->vtable->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));
+
if (context) {
MonoType *inflated = mono_class_inflate_generic_type (type, context);
result = mono_class_from_mono_type (inflated);
MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
if (m->method_args) {
result = mono_reflection_method_on_tb_inst_get_handle (m);
+ if (context)
+ result = mono_class_inflate_generic_method (result, context);
} else {
MonoType *type = mono_class_inflate_generic_type (mono_reflection_type_get_handle ((MonoReflectionType*)m->inst), context);
MonoClass *inflated_klass = mono_class_from_mono_type (type);
guint32
mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
- gboolean create_methodspec, gboolean register_token)
+ gboolean create_open_instance, gboolean register_token)
{
g_assert_not_reached ();
return 0;
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 */