#define MOVING_GC_REGISTER(addr)
#endif
+static gboolean is_usertype (MonoReflectionType *ref);
+static MonoReflectionType *mono_reflection_type_resolve_user_types (MonoReflectionType *type);
+
typedef struct {
char *p;
char *buf;
static gboolean is_sre_array (MonoClass *class);
static gboolean is_sre_byref (MonoClass *class);
static gboolean is_sre_pointer (MonoClass *class);
+static gboolean is_sre_type_builder (MonoClass *class);
+static gboolean is_sre_method_builder (MonoClass *class);
+static gboolean is_sre_ctor_builder (MonoClass *class);
+static gboolean is_sre_field_builder (MonoClass *class);
+static gboolean is_sr_mono_method (MonoClass *class);
+static gboolean is_sr_mono_cmethod (MonoClass *class);
+static gboolean is_sr_mono_field (MonoClass *class);
+
static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
-static MonoMethod * inflate_method (MonoReflectionGenericClass *type, MonoObject *obj);
+static MonoMethod * inflate_method (MonoReflectionType *type, MonoObject *obj);
#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 { \
if (mb->generic_params && create_methodspec)
return mono_image_get_methodspec_token_for_generic_method_definition (assembly, mb);
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, mb));
+ token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
if (token)
return token;
token = mono_image_get_methodref_token_for_methodbuilder (assembly, mb);
- g_hash_table_insert (assembly->handleref, mb, GUINT_TO_POINTER(token));
+ mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
return token;
}
ReflectionMethodBuilder rmb;
char *name;
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, mb));
+ token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
if (token)
return token;
name, method_builder_encode_signature (assembly, &rmb));
g_free (name);
- g_hash_table_insert (assembly->handleref, mb, GUINT_TO_POINTER(token));
+ mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
return token;
}
#endif
static MonoType*
get_field_on_inst_generic_type (MonoClassField *field)
{
+ MonoClass *class, *gtd;
MonoDynamicGenericClass *dgclass;
int field_index;
g_assert (is_field_on_inst (field));
dgclass = (MonoDynamicGenericClass*)field->parent->generic_class;
- field_index = field - dgclass->fields;
- g_assert (field_index >= 0 && field_index < dgclass->count_fields);
- return dgclass->field_generic_types [field_index];
+ if (field >= dgclass->fields && field - dgclass->fields < dgclass->count_fields) {
+ field_index = field - dgclass->fields;
+ return dgclass->field_generic_types [field_index];
+ }
+
+ class = field->parent;
+ gtd = class->generic_class->container_class;
+
+ if (field >= class->fields && field - class->fields < class->field.count) {
+ field_index = field - class->fields;
+ return gtd->fields [field_index].type;
+ }
+
+ g_assert_not_reached ();
+ return 0;
}
#ifndef DISABLE_REFLECTION_EMIT
guint32 token;
MonoClassField *field;
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, f));
+ token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
if (token)
return token;
g_assert (f->field->parent);
token = mono_image_get_memberref_token (assembly, &f->field->parent->byval_arg,
mono_field_get_name (f->field),
fieldref_encode_signature (assembly, field->parent->image, type));
- g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER(token));
+ mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
return token;
}
MonoClass *klass;
MonoGenericClass *gclass;
MonoDynamicGenericClass *dgclass;
- MonoReflectionFieldBuilder *fb = f->fb;
MonoType *type;
char *name;
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, f));
+ token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
if (token)
return token;
- type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst);
- klass = mono_class_from_mono_type (type);
- gclass = type->data.generic_class;
- g_assert (gclass->is_dynamic);
- dgclass = (MonoDynamicGenericClass *) gclass;
+ if (is_sre_field_builder (mono_object_class (f->fb))) {
+ MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)f->fb;
+ type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst);
+ klass = mono_class_from_mono_type (type);
+ gclass = type->data.generic_class;
+ g_assert (gclass->is_dynamic);
+ dgclass = (MonoDynamicGenericClass *) gclass;
+
+ name = mono_string_to_utf8 (fb->name);
+ token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name,
+ field_encode_signature (assembly, fb));
+ g_free (name);
+ } else if (is_sr_mono_field (mono_object_class (f->fb))) {
+ guint32 sig;
+ MonoClassField *field = ((MonoReflectionField *)f->fb)->field;
+
+ type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst);
+ klass = mono_class_from_mono_type (type);
- name = mono_string_to_utf8 (fb->name);
- token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name,
- field_encode_signature (assembly, fb));
- g_free (name);
- g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER (token));
+ sig = fieldref_encode_signature (assembly, field->parent->image, field->type);
+ token = mono_image_get_memberref_token (assembly, &klass->byval_arg, field->name, sig);
+ } else {
+ char *name = mono_type_get_full_name (mono_object_class (f->fb));
+ g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
+ }
+
+ mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER (token));
return token;
}
guint32 sig, token;
MonoClass *klass;
MonoGenericClass *gclass;
- MonoDynamicGenericClass *dgclass;
- MonoReflectionCtorBuilder *cb = c->cb;
- ReflectionMethodBuilder rmb;
MonoType *type;
- char *name;
/* A ctor cannot be a generic method, so we can ignore create_methodspec */
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, c));
+ token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, c));
if (token)
return token;
- type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst);
- klass = mono_class_from_mono_type (type);
- gclass = type->data.generic_class;
- g_assert (gclass->is_dynamic);
- dgclass = (MonoDynamicGenericClass *) gclass;
- reflection_methodbuilder_from_ctor_builder (&rmb, cb);
+ if (is_sre_ctor_builder (mono_object_class (c->cb))) {
+ MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder *)c->cb;
+ MonoDynamicGenericClass *dgclass;
+ ReflectionMethodBuilder rmb;
+ char *name;
- name = mono_string_to_utf8 (rmb.name);
+ type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst);
+ klass = mono_class_from_mono_type (type);
- sig = method_builder_encode_signature (assembly, &rmb);
+ gclass = type->data.generic_class;
+ g_assert (gclass->is_dynamic);
+ dgclass = (MonoDynamicGenericClass *) gclass;
+
+ reflection_methodbuilder_from_ctor_builder (&rmb, cb);
+
+ name = mono_string_to_utf8 (rmb.name);
+
+ sig = method_builder_encode_signature (assembly, &rmb);
+
+ token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
+ g_free (name);
+ } else if (is_sr_mono_cmethod (mono_object_class (c->cb))) {
+ MonoMethod *mm = ((MonoReflectionMethod *)c->cb)->method;
+
+ type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst);
+ klass = mono_class_from_mono_type (type);
+
+ sig = method_encode_signature (assembly, mono_method_signature (mm));
+ token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
+ } else {
+ char *name = mono_type_get_full_name (mono_object_class (c->cb));
+ g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
+ }
- token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
- g_free (name);
- g_hash_table_insert (assembly->handleref, c, GUINT_TO_POINTER (token));
+ mono_g_hash_table_insert (assembly->handleref_managed, c, GUINT_TO_POINTER (token));
return token;
}
static guint32
mono_image_get_method_on_inst_token (MonoDynamicImage *assembly, MonoReflectionMethodOnTypeBuilderInst *m, gboolean create_methodspec)
{
- guint32 sig, token;
- MonoClass *klass;
- MonoGenericClass *gclass;
- MonoReflectionMethodBuilder *mb = m->mb;
- ReflectionMethodBuilder rmb;
+ guint32 sig, token = 0;
MonoType *type;
- char *name;
+ MonoClass *klass;
if (m->method_args) {
MonoMethod *inflated;
return token;
}
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, m));
+ token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, m));
if (token)
return token;
- type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst);
- klass = mono_class_from_mono_type (type);
- gclass = type->data.generic_class;
- g_assert (gclass->is_dynamic);
- reflection_methodbuilder_from_method_builder (&rmb, mb);
+ if (is_sre_method_builder (mono_object_class (m->mb))) {
+ MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)m->mb;
+ MonoGenericClass *gclass;
+ ReflectionMethodBuilder rmb;
+ char *name;
- name = mono_string_to_utf8 (rmb.name);
+ type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst);
+ klass = mono_class_from_mono_type (type);
+ gclass = type->data.generic_class;
+ g_assert (gclass->is_dynamic);
+
+ reflection_methodbuilder_from_method_builder (&rmb, mb);
- sig = method_builder_encode_signature (assembly, &rmb);
+ name = mono_string_to_utf8 (rmb.name);
- token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
- g_free (name);
+ sig = method_builder_encode_signature (assembly, &rmb);
+
+ token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
+ g_free (name);
+ } else if (is_sr_mono_method (mono_object_class (m->mb))) {
+ MonoMethod *mm = ((MonoReflectionMethod *)m->mb)->method;
+
+ type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst);
+ klass = mono_class_from_mono_type (type);
- g_hash_table_insert (assembly->handleref, m, GUINT_TO_POINTER (token));
+ sig = method_encode_signature (assembly, mono_method_signature (mm));
+ token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
+ } else {
+ char *name = mono_type_get_full_name (mono_object_class (m->mb));
+ g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
+ }
+
+ mono_g_hash_table_insert (assembly->handleref_managed, m, GUINT_TO_POINTER (token));
return token;
}
guint32 token, pclass, parent, sig;
gchar *name;
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, fb));
+ token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, fb));
if (token)
return token;
token = MONO_TOKEN_MEMBER_REF | table->next_idx;
table->next_idx ++;
- g_hash_table_insert (assembly->handleref, fb, GUINT_TO_POINTER(token));
+ mono_g_hash_table_insert (assembly->handleref_managed, fb, GUINT_TO_POINTER(token));
g_free (name);
return token;
}
image->field_to_table_idx = g_hash_table_new (NULL, NULL);
image->method_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);
image->generic_def_objects = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
image->methodspec = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC);
g_hash_table_destroy (di->typeref);
if (di->handleref)
g_hash_table_destroy (di->handleref);
+ if (di->handleref_managed)
+ mono_g_hash_table_destroy (di->handleref_managed);
if (di->tokens)
mono_g_hash_table_destroy (di->tokens);
if (di->generic_def_objects)
assembly->run = assemblyb->access != 2;
assembly->save = assemblyb->access != 1;
+ assembly->domain = domain;
image = create_dynamic_mono_image (assembly, mono_string_to_utf8 (assemblyb->name), g_strdup ("RefEmit_YouForgotToDefineAModule"));
image->initial_image = TRUE;
MonoArray *type_args;
int i;
+ 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");
}
if (klass->reflection_info && !klass->wastypebuilder) {
+ gboolean is_type_done = TRUE;
+ /* Generic parameters have reflection_info set but they are not finished together with their enclosing type.
+ * We must ensure that once a type is finished we don't return a GenericTypeParameterBuilder.
+ * We can't simply close the types as this will interfere with other parts of the generics machinery.
+ */
+ if (klass->byval_arg.type == MONO_TYPE_MVAR || klass->byval_arg.type == MONO_TYPE_VAR) {
+ MonoGenericParam *gparam = klass->byval_arg.data.generic_param;
+
+ if (gparam->owner && gparam->owner->is_method) {
+ MonoMethod *method = gparam->owner->owner.method;
+ if (method && mono_class_get_generic_type_definition (method->klass)->wastypebuilder)
+ is_type_done = FALSE;
+ } else if (gparam->owner && !gparam->owner->is_method) {
+ MonoClass *klass = gparam->owner->owner.klass;
+ if (klass && mono_class_get_generic_type_definition (klass)->wastypebuilder)
+ is_type_done = FALSE;
+ }
+ }
+
/* g_assert_not_reached (); */
/* should this be considered an error condition? */
- if (!type->byref) {
+ if (is_type_done && !type->byref) {
mono_domain_unlock (domain);
mono_loader_unlock ();
return klass->reflection_info;
static MonoType*
mono_reflection_get_type_internal_dynamic (MonoImage *rootimage, MonoAssembly *assembly, MonoTypeNameParse *info, gboolean ignorecase)
{
- MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)mono_assembly_get_object (mono_domain_get (), assembly);
+ MonoReflectionAssemblyBuilder *abuilder;
MonoType *type;
int i;
g_assert (assembly->dynamic);
+ abuilder = (MonoReflectionAssemblyBuilder*)mono_assembly_get_object (((MonoDynamicAssembly*)assembly)->domain, assembly);
/* Enumerate all modules */
/* Need to copy since it will be freed later */
ainfo = aux->param_cattr [param];
+ if (!ainfo)
+ return NULL;
size = MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * ainfo->num_attrs;
res = g_malloc0 (size);
memcpy (res, ainfo, size);
static MonoReflectionType*
mono_reflection_type_get_underlying_system_type (MonoReflectionType* t)
{
- MonoMethod *method_get_underlying_system_type;
+ static MonoMethod *method_get_underlying_system_type = NULL;
+ MonoMethod *usertype_method;
- method_get_underlying_system_type = mono_object_get_virtual_method ((MonoObject *) t,
- mono_class_get_method_from_name (mono_object_class (t),
- "get_UnderlyingSystemType",
- 0));
- return (MonoReflectionType *) mono_runtime_invoke (method_get_underlying_system_type, t, NULL, NULL);
+ if (!method_get_underlying_system_type)
+ method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
+ usertype_method = mono_object_get_virtual_method ((MonoObject *) t, method_get_underlying_system_type);
+ return (MonoReflectionType *) mono_runtime_invoke (usertype_method, t, NULL, NULL);
}
#ifndef DISABLE_REFLECTION_EMIT
return class->image == mono_defaults.corlib;
}
-static gboolean
-is_usertype (MonoReflectionType *ref)
-{
- MonoClass *class = mono_object_class (ref);
- return class->image != mono_defaults.corlib || strcmp ("TypeDelegator", class->name) == 0;
-}
-
#define check_corlib_type_cached(_class, _namespace, _name) do { \
static MonoClass *cached_class; \
if (cached_class) \
check_corlib_type_cached (class, "System.Reflection", "MonoGenericClass");
}
+static gboolean
+is_sre_type_builder (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection.Emit", "TypeBuilder");
+}
+
+static gboolean
+is_sre_method_builder (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection.Emit", "MethodBuilder");
+}
+
+static gboolean
+is_sre_ctor_builder (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection.Emit", "ConstructorBuilder");
+}
+
+static gboolean
+is_sre_field_builder (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection.Emit", "FieldBuilder");
+}
+
+static gboolean
+is_sr_mono_method (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection", "MonoMethod");
+}
+
+static gboolean
+is_sr_mono_cmethod (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection", "MonoCMethod");
+}
+
+static gboolean
+is_sr_mono_field (MonoClass *class)
+{
+ check_corlib_type_cached (class, "System.Reflection", "MonoField");
+}
+
+
MonoType*
mono_reflection_type_get_handle (MonoReflectionType* ref)
{
if (is_usertype (ref)) {
ref = mono_reflection_type_get_underlying_system_type (ref);
- g_assert (!is_usertype (ref)); /*FIXME fail better*/
+ if (ref == NULL || is_usertype (ref))
+ return NULL;
if (ref->type)
return ref->type;
}
for (i = 0; i < count; ++i) {
MonoReflectionType *t = mono_array_get (gclass->type_arguments, gpointer, i);
types [i] = mono_reflection_type_get_handle (t);
+ if (!types[i]) {
+ g_free (types);
+ return NULL;
+ }
}
- res = mono_reflection_bind_generic_parameters ((MonoReflectionType*)gclass->generic_type, count, types);
+ res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types);
g_free (types);
g_assert (res);
gclass->type.type = res;
return NULL;
}
-static MonoReflectionType*
-mono_reflection_type_resolve_user_types (MonoReflectionType *type)
-{
- if (!type || type->type)
- return type;
-
- if (is_usertype (type)) {
- type = mono_reflection_type_get_underlying_system_type (type);
- if (is_usertype (type))
- mono_raise_exception (mono_get_exception_not_supported ("User defined subclasses of System.Type are not yet supported22"));
- }
- return type;
-}
void
mono_reflection_create_unmanaged_type (MonoReflectionType *type)
mono_reflection_type_get_handle (type);
}
+void
+mono_reflection_register_with_runtime (MonoReflectionType *type)
+{
+ MonoType *res = mono_reflection_type_get_handle (type);
+ MonoDomain *domain = mono_object_domain ((MonoObject*)type);
+ MonoClass *class;
+
+ if (!res)
+ mono_raise_exception (mono_get_exception_argument (NULL, "Invalid generic instantiation, one or more arguments are not proper user types"));
+
+ class = mono_class_from_mono_type (res);
+
+ mono_loader_lock (); /*same locking as mono_type_get_object*/
+ mono_domain_lock (domain);
+
+ if (!class->image->dynamic) {
+ 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);
+ mono_g_hash_table_insert (domain->type_hash, res, type);
+ }
+ mono_domain_unlock (domain);
+ mono_loader_unlock ();
+}
+
/**
* LOCKING: Assumes the loader lock is held.
*/
}
#endif /* !DISABLE_REFLECTION_EMIT */
+static gboolean
+is_usertype (MonoReflectionType *ref)
+{
+ MonoClass *class = mono_object_class (ref);
+ return class->image != mono_defaults.corlib || strcmp ("TypeDelegator", class->name) == 0;
+}
+
+static MonoReflectionType*
+mono_reflection_type_resolve_user_types (MonoReflectionType *type)
+{
+ if (!type || type->type)
+ return type;
+
+ if (is_usertype (type)) {
+ type = mono_reflection_type_get_underlying_system_type (type);
+ if (is_usertype (type))
+ mono_raise_exception (mono_get_exception_not_supported ("User defined subclasses of System.Type are not yet supported22"));
+ }
+
+ return type;
+}
/*
* Encode a value in a custom attribute stream of bytes.
* The value to encode is either supplied as an object in argument val
if (rmb->generic_params) {
int count = mono_array_length (rmb->generic_params);
- MonoGenericContainer *container;
+ MonoGenericContainer *container = rmb->generic_container;
+
+ g_assert (container);
- container = rmb->generic_container;
- if (container) {
- m->is_generic = TRUE;
- mono_method_set_generic_container (m, container);
- }
container->type_argc = count;
container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
container->owner.method = m;
+ m->is_generic = TRUE;
+ mono_method_set_generic_container (m, container);
+
for (i = 0; i < count; i++) {
MonoReflectionGenericParam *gp =
mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
domain = mono_object_domain (type);
- if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
+ if (is_sre_type_builder (mono_object_class (type))) {
tb = (MonoReflectionTypeBuilder *) type;
is_dynamic = TRUE;
- } else if (!strcmp (((MonoObject *) type)->vtable->klass->name, "MonoGenericClass")) {
+ } else if (is_sre_generic_instance (mono_object_class (type))) {
MonoReflectionGenericClass *rgi = (MonoReflectionGenericClass *) type;
+ MonoReflectionType *gtd = rgi->generic_type;
- tb = rgi->generic_type;
- is_dynamic = TRUE;
+ if (is_sre_type_builder (mono_object_class (gtd))) {
+ tb = (MonoReflectionTypeBuilder *)gtd;
+ is_dynamic = TRUE;
+ }
}
/* FIXME: fix the CreateGenericParameters protocol to avoid the two stage setup of TypeBuilders */
MONO_ARCH_SAVE_REGS;
+ /*FIXME but this no longer should happen*/
if (!strcmp (rmethod->object.vtable->klass->name, "MethodBuilder")) {
#ifndef DISABLE_REFLECTION_EMIT
MonoReflectionMethodBuilder *mb = NULL;
inflated = mono_class_inflate_generic_method (method, &tmp_context);
imethod = (MonoMethodInflated *) inflated;
+ /*FIXME but I think this is no longer necessary*/
if (method->klass->image->dynamic) {
MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image;
/*
}
static MonoMethod *
-inflate_method (MonoReflectionGenericClass *type, MonoObject *obj)
+inflate_method (MonoReflectionType *type, MonoObject *obj)
{
MonoMethod *method;
MonoClass *gklass;
- gklass = mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)type->generic_type));
+ MonoClass *type_class = mono_object_class (type);
+
+ if (is_sre_generic_instance (type_class)) {
+ MonoReflectionGenericClass *mgc = (MonoReflectionGenericClass*)type;
+ gklass = mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)mgc->generic_type));
+ } else if (is_sre_type_builder (type_class)) {
+ gklass = mono_class_from_mono_type (mono_reflection_type_get_handle (type));
+ } else if (type->type) {
+ gklass = mono_class_from_mono_type (type->type);
+ gklass = mono_class_get_generic_type_definition (gklass);
+ } else {
+ g_error ("Can't handle type %s", mono_type_get_full_name (mono_object_class (type)));
+ }
if (!strcmp (obj->vtable->klass->name, "MethodBuilder"))
if (((MonoReflectionMethodBuilder*)obj)->mhandle)
g_assert (gtype->type == MONO_TYPE_GENERICINST);
gclass = gtype->data.generic_class;
- g_assert (gclass->is_dynamic);
+ if (!gclass->is_dynamic)
+ return;
+
dgclass = (MonoDynamicGenericClass *) gclass;
if (dgclass->initialized)
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->count_properties = properties ? mono_array_length (properties) : 0;
- dgclass->count_events = events ? mono_array_length (events) : 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->properties = g_new0 (MonoProperty, dgclass->count_properties);
- dgclass->events = g_new0 (MonoEvent, dgclass->count_events);
dgclass->field_objects = g_new0 (MonoObject*, dgclass->count_fields);
dgclass->field_generic_types = g_new0 (MonoType*, dgclass->count_fields);
for (i = 0; i < dgclass->count_methods; i++) {
MonoObject *obj = mono_array_get (methods, gpointer, i);
- dgclass->methods [i] = inflate_method (type, obj);
+ 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 (type, obj);
+ dgclass->ctors [i] = inflate_method ((MonoReflectionType*)type, obj);
}
for (i = 0; i < dgclass->count_fields; i++) {
}
}
- for (i = 0; i < dgclass->count_properties; i++) {
- MonoObject *obj = mono_array_get (properties, gpointer, i);
- MonoProperty *property = &dgclass->properties [i];
-
- if (!strcmp (obj->vtable->klass->name, "PropertyBuilder")) {
- MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *) obj;
-
- property->parent = klass;
- property->attrs = pb->attrs;
- property->name = mono_string_to_utf8 (pb->name);
- if (pb->get_method)
- property->get = inflate_method (type, (MonoObject *) pb->get_method);
- if (pb->set_method)
- property->set = inflate_method (type, (MonoObject *) pb->set_method);
- } else if (!strcmp (obj->vtable->klass->name, "MonoProperty")) {
- *property = *((MonoReflectionProperty *) obj)->property;
- property->name = g_strdup (property->name);
-
- if (property->get)
- property->get = inflate_mono_method (klass, property->get, NULL);
- if (property->set)
- property->set = inflate_mono_method (klass, property->set, NULL);
- } else
- g_assert_not_reached ();
- }
-
- for (i = 0; i < dgclass->count_events; i++) {
- MonoObject *obj = mono_array_get (events, gpointer, i);
- MonoEvent *event = &dgclass->events [i];
-
- if (!strcmp (obj->vtable->klass->name, "EventBuilder")) {
- MonoReflectionEventBuilder *eb = (MonoReflectionEventBuilder *) obj;
-
- event->parent = klass;
- event->attrs = eb->attrs;
- event->name = mono_string_to_utf8 (eb->name);
- if (eb->add_method)
- event->add = inflate_method (type, (MonoObject *) eb->add_method);
- if (eb->remove_method)
- event->remove = inflate_method (type, (MonoObject *) eb->remove_method);
- } else if (!strcmp (obj->vtable->klass->name, "MonoEvent")) {
- *event = *((MonoReflectionMonoEvent *) obj)->event;
- event->name = g_strdup (event->name);
-
- if (event->add)
- event->add = inflate_mono_method (klass, event->add, NULL);
- if (event->remove)
- event->remove = inflate_mono_method (klass, event->remove, NULL);
- } else
- g_assert_not_reached ();
- }
-
dgclass->initialized = TRUE;
}
static void
-ensure_generic_class_runtime_vtable (MonoClass *klass)
+fix_partial_generic_class (MonoClass *klass)
{
MonoClass *gklass = klass->generic_class->container_class;
+ MonoDynamicGenericClass *dgclass;
int i;
if (klass->wastypebuilder)
return;
- ensure_runtime_vtable (gklass);
+ dgclass = (MonoDynamicGenericClass *) klass->generic_class;
- klass->method.count = gklass->method.count;
- klass->methods = mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
+ if (!dgclass->initialized)
+ return;
- for (i = 0; i < klass->method.count; i++) {
- klass->methods [i] = mono_class_inflate_generic_method_full (
- gklass->methods [i], klass, mono_class_get_context (klass));
+ if (klass->method.count != gklass->method.count) {
+ klass->method.count = gklass->method.count;
+ klass->methods = mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
+
+ for (i = 0; i < klass->method.count; i++) {
+ klass->methods [i] = mono_class_inflate_generic_method_full (
+ gklass->methods [i], klass, mono_class_get_context (klass));
+ }
}
- klass->interface_count = gklass->interface_count;
- klass->interfaces = mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
- for (i = 0; i < klass->interface_count; ++i) {
- MonoType *iface_type = mono_class_inflate_generic_type (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass));
- klass->interfaces [i] = mono_class_from_mono_type (iface_type);
- mono_metadata_free_type (iface_type);
+ if (klass->interface_count && klass->interface_count != gklass->interface_count) {
+ klass->interface_count = gklass->interface_count;
+ klass->interfaces = mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
+ klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
+
+ for (i = 0; i < gklass->interface_count; ++i) {
+ MonoType *iface_type = mono_class_inflate_generic_type (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass));
+ klass->interfaces [i] = mono_class_from_mono_type (iface_type);
+ mono_metadata_free_type (iface_type);
- ensure_runtime_vtable (klass->interfaces [i]);
+ ensure_runtime_vtable (klass->interfaces [i]);
+ }
+ klass->interfaces_inited = 1;
+ }
+
+ if (klass->field.count != gklass->field.count) {
+ klass->field.count = gklass->field.count;
+ klass->fields = image_g_new0 (klass->image, MonoClassField, klass->field.count);
+
+ for (i = 0; i < klass->field.count; i++) {
+ klass->fields [i] = gklass->fields [i];
+ klass->fields [i].parent = klass;
+ klass->fields [i].type = mono_class_inflate_generic_type (gklass->fields [i].type, mono_class_get_context (klass));
+ }
}
- klass->interfaces_inited = 1;
/*We can only finish with this klass once it's parent has as well*/
if (gklass->wastypebuilder)
return;
}
+static void
+ensure_generic_class_runtime_vtable (MonoClass *klass)
+{
+ MonoClass *gklass = klass->generic_class->container_class;
+
+ ensure_runtime_vtable (gklass);
+
+ fix_partial_generic_class (klass);
+}
+
static void
ensure_runtime_vtable (MonoClass *klass)
{
for (i = 0; i < klass->method.count; ++i)
klass->methods [i]->slot = i;
+ klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
mono_class_setup_interface_offsets (klass);
mono_class_setup_interface_id (klass);
}
}
static gboolean
-remove_instantiations_of (gpointer key,
+remove_instantiations_of_and_ensure_contents (gpointer key,
gpointer value,
gpointer user_data)
{
MonoType *type = (MonoType*)key;
MonoClass *klass = (MonoClass*)user_data;
- if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass))
+ if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
+ fix_partial_generic_class (mono_class_from_mono_type (type)); //Ensure it's safe to use it.
return TRUE;
- else
+ } else
return FALSE;
}
* If we are a generic TypeBuilder, there might be instantiations in the type cache
* which have type System.Reflection.MonoGenericClass, but after the type is created,
* we want to return normal System.MonoType objects, so clear these out from the cache.
+ *
+ * Together with this we must ensure the contents of all instances to match the created type.
*/
if (domain->type_hash && klass->generic_container)
- mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of, klass);
+ mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, klass);
mono_domain_unlock (domain);
mono_loader_unlock ();
sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
sig->hasthis = helper->call_conv & 32 ? 1 : 0;
- if (helper->call_conv == 0) /* unmanaged */
+ if (helper->unmanaged_call_conv) { /* unmanaged */
sig->call_convention = helper->unmanaged_call_conv - 1;
- else
- if (helper->call_conv & 0x02)
- sig->call_convention = MONO_CALL_VARARG;
- else
+ sig->pinvoke = TRUE;
+ } else if (helper->call_conv & 0x02) {
+ sig->call_convention = MONO_CALL_VARARG;
+ } else {
sig->call_convention = MONO_CALL_DEFAULT;
+ }
sig->param_count = nargs;
/* TODO: Copy type ? */
MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
MonoClass *inflated;
MonoType *type;
+ MonoClassField *field;
+
+ if (is_sre_field_builder (mono_object_class (f->fb)))
+ field = ((MonoReflectionFieldBuilder*)f->fb)->handle;
+ else if (is_sr_mono_field (mono_object_class (f->fb)))
+ field = ((MonoReflectionField*)f->fb)->field;
+ else
+ g_error ("resolve_object:: can't handle a FTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (f->fb)));
type = mono_class_inflate_generic_type (mono_reflection_type_get_handle ((MonoReflectionType*)f->inst), context);
inflated = mono_class_from_mono_type (type);
- g_assert (f->fb->handle);
- result = mono_class_get_field_from_name (inflated, mono_field_get_name (f->fb->handle));
+ result = field = mono_class_get_field_from_name (inflated, mono_field_get_name (field));
+ ensure_complete_type (field->parent);
g_assert (result);
mono_metadata_free_type (type);
*handle_class = mono_defaults.fieldhandle_class;
MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
MonoType *type = mono_class_inflate_generic_type (mono_reflection_type_get_handle ((MonoReflectionType*)c->inst), context);
MonoClass *inflated_klass = mono_class_from_mono_type (type);
- g_assert (c->cb->mhandle);
- result = inflate_mono_method (inflated_klass, c->cb->mhandle, (MonoObject*)c->cb);
+ MonoMethod *method;
+
+ if (is_sre_ctor_builder (mono_object_class (c->cb)))
+ method = ((MonoReflectionCtorBuilder *)c->cb)->mhandle;
+ else if (is_sr_mono_cmethod (mono_object_class (c->cb)))
+ method = ((MonoReflectionMethod *)c->cb)->method;
+ else
+ g_error ("resolve_object:: can't handle a CTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (c->cb)));
+
+ result = inflate_mono_method (inflated_klass, method, (MonoObject*)c->cb);
*handle_class = mono_defaults.methodhandle_class;
mono_metadata_free_type (type);
} else if (strcmp (obj->vtable->klass->name, "MethodOnTypeBuilderInst") == 0) {
} 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);
- g_assert (m->mb->mhandle);
- result = inflate_mono_method (inflated_klass, m->mb->mhandle, (MonoObject*)m->mb);
+ MonoMethod *method;
+
+ if (is_sre_method_builder (mono_object_class (m->mb)))
+ method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
+ else if (is_sr_mono_method (mono_object_class (m->mb)))
+ 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, method, (MonoObject*)m->mb);
mono_metadata_free_type (type);
}
*handle_class = mono_defaults.methodhandle_class;