static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError *error);
static guint32 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error);
static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb);
+static gboolean reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error);
static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
#endif
static gboolean is_sre_method_builder (MonoClass *klass);
static gboolean is_sre_field_builder (MonoClass *klass);
static gboolean is_sre_gparam_builder (MonoClass *klass);
+static gboolean is_sre_enum_builder (MonoClass *klass);
static gboolean is_sr_mono_method (MonoClass *klass);
static gboolean is_sr_mono_field (MonoClass *klass);
return token;
}
-void
-mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error)
-{
- MonoReflectionTypeBuilder *tb;
-
- mono_error_init (error);
-
- if (!is_sre_type_builder(mono_object_class (type)))
- return;
- tb = (MonoReflectionTypeBuilder *)type;
-
- if (tb && tb->generic_container)
- mono_reflection_create_generic_class (tb, error);
-}
-
static guint32
mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error)
{
check_corlib_type_cached (klass, "System.Reflection.Emit", "GenericTypeParameterBuilder");
}
+static gboolean
+is_sre_enum_builder (MonoClass *klass)
+{
+ check_corlib_type_cached (klass, "System.Reflection.Emit", "EnumBuilder");
+}
+
gboolean
mono_is_sre_method_on_tb_inst (MonoClass *klass)
{
param->param.num = gparam->index;
if (gparam->mbuilder) {
- g_assert (gparam->mbuilder->generic_container);
+ if (!gparam->mbuilder->generic_container) {
+ gparam->mbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (image, sizeof (MonoGenericContainer));
+ gparam->mbuilder->generic_container->is_method = TRUE;
+ /*
+ * Cannot set owner.method, since the MonoMethod is not created yet.
+ * Set the image field instead, so type_in_image () works.
+ */
+ gparam->mbuilder->generic_container->is_anonymous = TRUE;
+ gparam->mbuilder->generic_container->owner.image = image;
+ }
param->param.owner = gparam->mbuilder->generic_container;
} else if (gparam->tbuilder) {
- g_assert (gparam->tbuilder->generic_container);
- param->param.owner = gparam->tbuilder->generic_container;
+ MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)(gparam->tbuilder), error);
+ mono_error_assert_ok (error);
+ MonoClass *owner = mono_class_from_mono_type (type);
+ g_assert (owner->generic_container);
+ param->param.owner = owner->generic_container;
}
pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param);
mono_image_append_class_to_reflection_info_set (pklass);
return &pklass->byval_arg;
+ } else if (is_sre_enum_builder (klass)) {
+ MonoReflectionEnumBuilder *ebuilder = (MonoReflectionEnumBuilder *)ref;
+
+ return mono_reflection_type_get_handle ((MonoReflectionType*)ebuilder->tb, error);
+ } else if (is_sre_type_builder (klass)) {
+ MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)ref;
+
+ /* This happens when a finished type references an unfinished one. Have to create the minimal type */
+ reflection_setup_internal_class (tb, error);
+ mono_error_assert_ok (error);
+ g_assert (ref->type);
+ return ref->type;
}
g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
tb->type.type = &klass->byval_arg;
if (tb->nesting_type) {
+ reflection_setup_internal_class ((MonoReflectionTypeBuilder*)tb->nesting_type, error);
g_assert (tb->nesting_type->type);
MonoType *nesting_type = mono_reflection_type_get_handle (tb->nesting_type, error);
if (!is_ok (error)) goto failure;
return FALSE;
}
-/**
- * ves_icall_TypeBuilder_setup_internal_class:
- * @tb: a TypeBuilder object
- *
- * (icall)
- * Creates a MonoClass that represents the TypeBuilder.
- * This is a trick that lets us simplify a lot of reflection code
- * (and will allow us to support Build and Run assemblies easier).
- *
- */
-void
-ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
-{
- MonoError error;
- (void) reflection_setup_internal_class (tb, &error);
- mono_error_set_pending_exception (&error);
-}
-
/**
* mono_reflection_create_generic_class:
* @tb: a TypeBuilder object
*
* Creates the generic class after all generic parameters have been added.
* On success returns TRUE, on failure returns FALSE and sets @error.
- *
*/
gboolean
mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
{
-
MonoClass *klass;
int count, i;
mono_error_init (error);
+ reflection_setup_internal_class (tb, error);
+
klass = mono_class_from_mono_type (tb->type.type);
count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
- if (klass->generic_container || (count == 0))
+ if (count == 0)
return TRUE;
- g_assert (tb->generic_container && (tb->generic_container->owner.klass == klass));
-
klass->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
klass->generic_container->owner.klass = klass;
if (rmb->generic_params) {
int count = mono_array_length (rmb->generic_params);
- MonoGenericContainer *container = rmb->generic_container;
-
- g_assert (container);
+ MonoGenericContainer *container;
+ container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
+ container->is_method = TRUE;
+ container->is_anonymous = FALSE;
container->type_argc = count;
container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
container->owner.method = m;
- container->is_anonymous = FALSE; // Method is now known, container is no longer anonymous
m->is_generic = TRUE;
mono_method_set_generic_container (m, container);
mono_error_assert_ok (error);
MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param;
container->type_params [i] = *param;
+ container->type_params [i].param.owner = container;
+
+ gp->type.type->data.generic_param = (MonoGenericParam*)&container->type_params [i];
}
/*
MonoMethodSignature *sig;
mono_loader_lock ();
+
+ if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
+ return NULL;
+
g_assert (klass->image != NULL);
sig = ctor_builder_to_signature (klass->image, mb, error);
mono_loader_unlock ();
return_val_if_nok (error, NULL);
- if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error))
- return NULL;
-
mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
return_val_if_nok (error, NULL);
mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
mono_error_init (error);
mono_loader_lock ();
+
+ if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
+ return NULL;
+
g_assert (klass->image != NULL);
sig = method_builder_to_signature (klass->image, mb, error);
mono_loader_unlock ();
return_val_if_nok (error, NULL);
- if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error))
- return NULL;
-
mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
return_val_if_nok (error, NULL);
mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
mono_error_init (&error);
+ mono_reflection_create_generic_class (tb, &error);
+ mono_error_assert_ok (&error);
+
domain = mono_object_domain (tb);
klass = mono_class_from_mono_type (tb->type.type);
for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
mono_class_alloc_ext (klass);
+
+ if (!subtb->type.type) {
+ reflection_setup_internal_class (subtb, &error);
+ mono_error_assert_ok (&error);
+ }
+
MonoType *subtype = mono_reflection_type_get_handle ((MonoReflectionType*)subtb, &error);
if (!is_ok (&error)) goto failure;
klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, mono_class_from_mono_type (subtype));
return NULL;
}
-static gboolean
-reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam, MonoError *error)
-{
- MonoImage *image;
-
- mono_error_init (error);
-
- image = &gparam->tbuilder->module->dynamic_image->image;
-
- if (gparam->mbuilder) {
- if (!gparam->mbuilder->generic_container) {
- MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->mbuilder->type, error);
- return_val_if_nok (error, FALSE);
-
- MonoClass *klass = mono_class_from_mono_type (tb);
- gparam->mbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
- gparam->mbuilder->generic_container->is_method = TRUE;
- /*
- * Cannot set owner.method, since the MonoMethod is not created yet.
- * Set the image field instead, so type_in_image () works.
- */
- gparam->mbuilder->generic_container->is_anonymous = TRUE;
- gparam->mbuilder->generic_container->owner.image = klass->image;
- }
- } else if (gparam->tbuilder) {
- if (!gparam->tbuilder->generic_container) {
- MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->tbuilder, error);
- return_val_if_nok (error, FALSE);
- MonoClass *klass = mono_class_from_mono_type (tb);
- gparam->tbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
- gparam->tbuilder->generic_container->owner.klass = klass;
- }
- }
-
- return TRUE;
-}
-
-void
-ves_icall_GenericTypeParameterBuilder_initialize (MonoReflectionGenericParam *gparam)
-{
- MonoError error;
- (void) reflection_initialize_generic_parameter (gparam, &error);
- mono_error_set_pending_exception (&error);
-}
-
-
typedef struct {
MonoMethod *handle;
MonoDomain *domain;
return obj;
}
-/**
- * ves_icall_TypeBuilder_create_generic_class:
- * @tb: a TypeBuilder object
- *
- * (icall)
- * Creates the generic class after all generic parameters have been added.
- */
-void
-ves_icall_TypeBuilder_create_generic_class (MonoReflectionTypeBuilder *tb)
-{
- MonoError error;
- (void) mono_reflection_create_generic_class (tb, &error);
- mono_error_set_pending_exception (&error);
-}
-
#ifndef DISABLE_REFLECTION_EMIT
MonoArray*
ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)