#include "mono/utils/checked-build.h"
#include "mono/utils/mono-digest.h"
-void
-mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
-{
- mono_gc_deregister_root ((char*) &entry->gparam);
- g_free (entry);
-}
-
static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, System.Runtime.InteropServices, MarshalAsAttribute);
static GENERATE_GET_CLASS_WITH_CACHE (module_builder, System.Reflection.Emit, ModuleBuilder);
static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error);
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 mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
ta = klass->image->assembly;
if (assembly_is_dynamic (ta) || (ta == ass)) {
- if (klass->generic_class || klass->generic_container)
+ if (mono_class_is_ginst (klass) || mono_class_is_gtd (klass))
/* For generic type definitions, we want T, while REFLECTION returns T<K> */
return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
else
}
#endif
-
guint32
mono_reflection_resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
{
return token;
}
-static guint32
-mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error)
-{
- guint32 token, parent, sig;
- ReflectionMethodBuilder rmb;
- MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)method->type;
-
- mono_error_init (error);
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
- if (token)
- return token;
-
- if (!mono_reflection_methodbuilder_from_method_builder (&rmb, method, error))
- return 0;
-
- /*
- * A methodref signature can't contain an unmanaged calling convention.
- * Since some flags are encoded as part of call_conv, we need to check against it.
- */
- if ((rmb.call_conv & ~0x60) != MONO_CALL_DEFAULT && (rmb.call_conv & ~0x60) != MONO_CALL_VARARG)
- rmb.call_conv = (rmb.call_conv & 0x60) | MONO_CALL_DEFAULT;
-
- sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error);
- return_val_if_nok (error, 0);
-
- if (tb->generic_params) {
- parent = mono_dynimage_encode_generic_typespec (assembly, tb, error);
- return_val_if_nok (error, 0);
- } else {
- MonoType *t = mono_reflection_type_get_handle ((MonoReflectionType*)rmb.type, error);
- return_val_if_nok (error, 0);
-
- parent = mono_image_typedef_or_ref (assembly, t);
- }
-
- char *name = mono_string_to_utf8_checked (method->name, error);
- return_val_if_nok (error, 0);
-
- token = mono_image_add_memberef_row (assembly, parent, name, sig);
- g_free (name);
-
- g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
-
- return token;
-}
-
static guint32
mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
const gchar *name, guint32 sig)
return token;
}
-static guint32
-mono_image_get_methodspec_token_for_generic_method_definition (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, MonoError *error)
-{
- MonoDynamicTable *table;
- guint32 *values;
- guint32 token, mtoken = 0;
-
- mono_error_init (error);
- token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->methodspec, mb));
- if (token)
- return token;
-
- table = &assembly->tables [MONO_TABLE_METHODSPEC];
-
- mtoken = mono_image_get_methodref_token_for_methodbuilder (assembly, mb, error);
- if (!mono_error_ok (error))
- return 0;
-
- switch (mono_metadata_token_table (mtoken)) {
- case MONO_TABLE_MEMBERREF:
- mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
- break;
- case MONO_TABLE_METHOD:
- mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
- break;
- default:
- g_assert_not_reached ();
- }
-
- if (assembly->save) {
- alloc_table (table, table->rows + 1);
- values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
- values [MONO_METHODSPEC_METHOD] = mtoken;
- values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_definition_sig (assembly, mb);
- }
-
- token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
- table->next_idx ++;
-
- mono_g_hash_table_insert (assembly->methodspec, mb, GUINT_TO_POINTER(token));
- return token;
-}
#endif
static gboolean
is_field_on_inst (MonoClassField *field)
{
- return field->parent->generic_class && field->parent->generic_class->is_dynamic;
+ return mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->is_dynamic;
}
#ifndef DISABLE_REFLECTION_EMIT
if (token)
return token;
- if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) {
+ if (mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->container_class && mono_class_get_generic_class (field->parent)->container_class->fields) {
int index = field - field->parent->fields;
- type = mono_field_get_type (&field->parent->generic_class->container_class->fields [index]);
+ type = mono_field_get_type (&mono_class_get_generic_class (field->parent)->container_class->fields [index]);
} else {
type = mono_field_get_type (field);
}
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)
{
return 0;
}
- if (strcmp (klass->name, "MethodBuilder") == 0) {
- /* These are handled in managed code */
- g_assert_not_reached ();
- } else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
- /* These are handled in managed code */
- g_assert_not_reached ();
- } else if (strcmp (klass->name, "FieldBuilder") == 0) {
- /* These are handled in managed code */
- g_assert_not_reached ();
- } else if (strcmp (klass->name, "TypeBuilder") == 0) {
- /* These are handled in managed code */
- g_assert_not_reached ();
- } else if (strcmp (klass->name, "RuntimeType") == 0) {
+ if (strcmp (klass->name, "RuntimeType") == 0) {
MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error);
return_val_if_nok (error, 0);
MonoClass *mc = mono_class_from_mono_type (type);
token = mono_metadata_token_from_dor (
- mono_dynimage_encode_typedef_or_ref_full (assembly, type, mc->generic_container == NULL || create_open_instance));
- } else if (strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
- /* These are handled in managed code */
- g_assert_not_reached ();
+ mono_dynimage_encode_typedef_or_ref_full (assembly, type, !mono_class_is_gtd (mc) || create_open_instance));
} else if (strcmp (klass->name, "MonoCMethod") == 0 ||
strcmp (klass->name, "MonoMethod") == 0) {
MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
else
token = mono_image_get_inflated_method_token (assembly, m->method);
} else if ((m->method->klass->image == &assembly->image) &&
- !m->method->klass->generic_class) {
+ !mono_class_is_ginst (m->method->klass)) {
static guint32 method_table_idx = 0xffffff;
if (m->method->klass->wastypebuilder) {
/* we use the same token as the one that was assigned
return_val_if_nok (error, 0);
token = mono_metadata_token_from_dor (
mono_image_typedef_or_ref (assembly, type));
- } else if (is_sre_generic_instance (klass) || is_sre_array (klass) || is_sre_byref (klass) || is_sre_pointer (klass)) {
- /* These are handled in managed code */
- g_assert_not_reached ();
- } else if (strcmp (klass->name, "FieldOnTypeBuilderInst") == 0) {
- /* These are handled in managed code */
- g_assert_not_reached ();
- } else if (strcmp (klass->name, "ConstructorOnTypeBuilderInst") == 0) {
- /* These are handled in managed code */
- g_assert_not_reached ();
- } else if (strcmp (klass->name, "MethodOnTypeBuilderInst") == 0) {
- /* These are handled in managed code */
- g_assert_not_reached ();
} else {
g_error ("requested token for %s\n", klass->name);
}
static gboolean
is_sre_generic_instance (MonoClass *klass)
{
- check_corlib_type_cached (klass, "System.Reflection", "MonoGenericClass");
+ check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilderInstantiation");
}
static gboolean
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 (mono_class_is_gtd (owner));
+ param->param.owner = mono_class_get_generic_container (owner);
}
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));
return FALSE;
}
-void
-mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error)
-{
- mono_error_init (error);
-}
-
#endif /* !DISABLE_REFLECTION_EMIT */
return TRUE;
}
- klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, sizeof (MonoClass));
+ /*
+ * The size calculation here warrants some explaining.
+ * reflection_setup_internal_class is called too early, well before we know whether the type will be a GTD or DEF,
+ * meaning we need to alloc enough space to morth a def into a gtd.
+ */
+ klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, MAX (sizeof (MonoClassDef), sizeof (MonoClassGtd)));
+ klass->class_kind = MONO_CLASS_DEF;
klass->image = &tb->module->dynamic_image->image;
if (!is_ok (error))
goto failure;
klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
- klass->flags = tb->attrs;
+ mono_class_set_flags (klass, tb->attrs);
mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
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;
}
/**
- * 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:
+ * reflection_create_generic_class:
* @tb: a TypeBuilder object
* @error: set on error
*
* 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)
+static gboolean
+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));
+ MonoGenericContainer *generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
- klass->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
+ generic_container->owner.klass = klass;
+ generic_container->type_argc = count;
+ generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
- klass->generic_container->owner.klass = klass;
- klass->generic_container->type_argc = count;
- klass->generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
+ klass->class_kind = MONO_CLASS_GTD;
+ mono_class_set_generic_container (klass, generic_container);
- klass->is_generic = 1;
for (i = 0; i < count; i++) {
MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error);
return_val_if_nok (error, FALSE);
MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param;
- klass->generic_container->type_params [i] = *param;
+ generic_container->type_params [i] = *param;
/*Make sure we are a diferent type instance */
- klass->generic_container->type_params [i].param.owner = klass->generic_container;
- klass->generic_container->type_params [i].info.pklass = NULL;
- klass->generic_container->type_params [i].info.flags = gparam->attrs;
+ generic_container->type_params [i].param.owner = generic_container;
+ generic_container->type_params [i].info.pklass = NULL;
+ generic_container->type_params [i].info.flags = gparam->attrs;
- g_assert (klass->generic_container->type_params [i].param.owner);
+ g_assert (generic_container->type_params [i].param.owner);
}
- klass->generic_container->context.class_inst = mono_get_shared_generic_inst (klass->generic_container);
+ generic_container->context.class_inst = mono_get_shared_generic_inst (generic_container);
return TRUE;
}
image = dynamic ? NULL : klass->image;
if (!dynamic)
- g_assert (!klass->generic_class);
+ g_assert (!mono_class_is_ginst (klass));
mono_loader_lock ();
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];
+
+ MonoClass *gklass = mono_class_from_mono_type (gp_type);
+ gklass->wastypebuilder = TRUE;
}
/*
}
}
- if (klass->generic_container) {
- container->parent = klass->generic_container;
- container->context.class_inst = klass->generic_container->context.class_inst;
+ if (mono_class_is_gtd (klass)) {
+ container->parent = mono_class_get_generic_container (klass);
+ container->context.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
}
container->context.method_inst = mono_get_shared_generic_inst (container);
}
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);
static gboolean
fix_partial_generic_class (MonoClass *klass, MonoError *error)
{
- MonoClass *gklass = klass->generic_class->container_class;
+ MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
int i;
mono_error_init (error);
return TRUE;
if (klass->parent != gklass->parent) {
- MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, error);
+ MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &mono_class_get_generic_class (klass)->context, error);
if (mono_error_ok (error)) {
MonoClass *parent = mono_class_from_mono_type (parent_type);
mono_metadata_free_type (parent_type);
}
}
- if (!klass->generic_class->need_sync)
+ if (!mono_class_get_generic_class (klass)->need_sync)
return TRUE;
- if (klass->method.count != gklass->method.count) {
- klass->method.count = gklass->method.count;
- klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
+ int mcount = mono_class_get_method_count (klass);
+ int gmcount = mono_class_get_method_count (gklass);
+ if (mcount != gmcount) {
+ mono_class_set_method_count (klass, gmcount);
+ klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (gmcount + 1));
- for (i = 0; i < klass->method.count; i++) {
+ for (i = 0; i < gmcount; i++) {
klass->methods [i] = mono_class_inflate_generic_method_full_checked (
gklass->methods [i], klass, mono_class_get_context (klass), error);
mono_error_assert_ok (error);
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);
+ int fcount = mono_class_get_field_count (klass);
+ int gfcount = mono_class_get_field_count (gklass);
+ if (fcount != gfcount) {
+ mono_class_set_field_count (klass, gfcount);
+ klass->fields = image_g_new0 (klass->image, MonoClassField, gfcount);
- for (i = 0; i < klass->field.count; i++) {
+ for (i = 0; i < gfcount; i++) {
klass->fields [i] = gklass->fields [i];
klass->fields [i].parent = klass;
klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error);
static gboolean
ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
{
- MonoClass *gklass = klass->generic_class->container_class;
+ MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
mono_error_init (error);
mono_error_init (error);
- if (!image_is_dynamic (klass->image) || (!tb && !klass->generic_class) || klass->wastypebuilder)
+ if (!image_is_dynamic (klass->image) || (!tb && !mono_class_is_ginst (klass)) || klass->wastypebuilder)
return TRUE;
if (klass->parent)
if (!ensure_runtime_vtable (klass->parent, error))
if (tb) {
num = tb->ctors? mono_array_length (tb->ctors): 0;
num += tb->num_methods;
- klass->method.count = num;
+ mono_class_set_method_count (klass, num);
klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
num = tb->ctors? mono_array_length (tb->ctors): 0;
for (i = 0; i < num; ++i) {
}
klass->interfaces_inited = 1;
}
- } else if (klass->generic_class){
+ } else if (mono_class_is_ginst (klass)){
if (!ensure_generic_class_runtime_vtable (klass, error)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error));
return FALSE;
}
}
- if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+ if (mono_class_is_interface (klass) && !mono_class_is_ginst (klass)) {
int slot_num = 0;
- for (i = 0; i < klass->method.count; ++i) {
+ int mcount = mono_class_get_method_count (klass);
+ for (i = 0; i < mcount; ++i) {
MonoMethod *im = klass->methods [i];
if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
im->slot = slot_num++;
*num_overrides = onum;
}
+/* This initializes the same data as mono_class_setup_fields () */
static void
typebuilder_setup_fields (MonoClass *klass, MonoError *error)
{
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass);
MonoReflectionFieldBuilder *fb;
MonoClassField *field;
+ MonoClassExt *ext;
MonoImage *image = klass->image;
const char *p, *p2;
- int i;
- guint32 len, idx, real_size = 0;
+ int i, instance_size, packing_size = 0;
+ guint32 len, idx;
+
+ if (klass->parent) {
+ if (!klass->parent->size_inited)
+ mono_class_init (klass->parent);
+ instance_size = klass->parent->instance_size;
+ } else {
+ instance_size = sizeof (MonoObject);
+ }
- klass->field.count = tb->num_fields;
- klass->field.first = 0;
+ int fcount = tb->num_fields;
+ mono_class_set_field_count (klass, fcount);
mono_error_init (error);
if (tb->class_size) {
- if ((tb->packing_size & 0xffffff00) != 0) {
- char *err_msg = mono_image_strdup_printf (klass->image, "Could not load struct '%s' with packing size %d >= 256", klass->name, tb->packing_size);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
- return;
- }
- klass->packing_size = tb->packing_size;
- real_size = klass->instance_size + tb->class_size;
- }
-
- if (!klass->field.count) {
- klass->instance_size = MAX (klass->instance_size, real_size);
- return;
+ packing_size = tb->packing_size;
+ instance_size += tb->class_size;
}
- klass->fields = image_g_new0 (image, MonoClassField, klass->field.count);
+ klass->fields = image_g_new0 (image, MonoClassField, fcount);
mono_class_alloc_ext (klass);
- klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->field.count);
+ ext = mono_class_get_ext (klass);
+ ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, fcount);
/*
This is, guess what, a hack.
The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
*/
klass->size_inited = 1;
- for (i = 0; i < klass->field.count; ++i) {
+ for (i = 0; i < fcount; ++i) {
MonoArray *rva_data;
fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
field = &klass->fields [i];
+ field->parent = klass;
field->name = mono_string_to_utf8_image (image, fb->name, error);
if (!mono_error_ok (error))
return;
size_t size = mono_array_length (rva_data);
char *data = (char *)mono_image_alloc (klass->image, size);
memcpy (data, base, size);
- klass->ext->field_def_values [i].data = data;
+ ext->field_def_values [i].data = data;
}
if (fb->offset != -1)
field->offset = fb->offset;
- field->parent = klass;
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;
- idx = mono_dynimage_encode_constant (assembly, fb->def_value, &klass->ext->field_def_values [i].def_type);
+ idx = mono_dynimage_encode_constant (assembly, fb->def_value, &ext->field_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->field_def_values [i].data = (const char *)mono_image_alloc (image, len);
- memcpy ((gpointer)klass->ext->field_def_values [i].data, p, len);
+ ext->field_def_values [i].data = (const char *)mono_image_alloc (image, len);
+ memcpy ((gpointer)ext->field_def_values [i].data, p, len);
}
}
- klass->instance_size = MAX (klass->instance_size, real_size);
- mono_class_layout_fields (klass, klass->instance_size);
+ mono_class_layout_fields (klass, instance_size, packing_size, TRUE);
}
static void
MonoReflectionPropertyBuilder *pb;
MonoImage *image = klass->image;
MonoProperty *properties;
+ MonoClassExt *ext;
int i;
mono_error_init (error);
- if (!klass->ext)
- klass->ext = image_g_new0 (image, MonoClassExt, 1);
+ ext = mono_class_get_ext (klass);
+ if (!ext)
+ mono_class_set_ext (klass, ext = image_g_new0 (image, MonoClassExt, 1));
- klass->ext->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
- klass->ext->property.first = 0;
+ ext->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
+ ext->property.first = 0;
- properties = image_g_new0 (image, MonoProperty, klass->ext->property.count);
- klass->ext->properties = properties;
- for (i = 0; i < klass->ext->property.count; ++i) {
+ properties = image_g_new0 (image, MonoProperty, ext->property.count);
+ ext->properties = properties;
+ for (i = 0; i < ext->property.count; ++i) {
pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
properties [i].parent = klass;
properties [i].attrs = pb->attrs;
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);
+ if (!ext->prop_def_values)
+ ext->prop_def_values = image_g_new0 (image, MonoFieldDefaultValue, ext->property.count);
properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
- idx = mono_dynimage_encode_constant (assembly, pb->def_value, &klass->ext->prop_def_values [i].def_type);
+ idx = mono_dynimage_encode_constant (assembly, pb->def_value, &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 = (const char *)mono_image_alloc (image, len);
- memcpy ((gpointer)klass->ext->prop_def_values [i].data, p, len);
+ ext->prop_def_values [i].data = (const char *)mono_image_alloc (image, len);
+ memcpy ((gpointer)ext->prop_def_values [i].data, p, len);
}
}
}
MonoReflectionEventBuilder *eb;
MonoImage *image = klass->image;
MonoEvent *events;
+ MonoClassExt *ext;
int i;
mono_error_init (error);
- if (!klass->ext)
- klass->ext = image_g_new0 (image, MonoClassExt, 1);
+ ext = mono_class_get_ext (klass);
+ if (!ext)
+ mono_class_set_ext (klass, ext = image_g_new0 (image, MonoClassExt, 1));
- klass->ext->event.count = tb->events ? mono_array_length (tb->events) : 0;
- klass->ext->event.first = 0;
+ ext->event.count = tb->events ? mono_array_length (tb->events) : 0;
+ ext->event.first = 0;
- events = image_g_new0 (image, MonoEvent, klass->ext->event.count);
- klass->ext->events = events;
- for (i = 0; i < klass->ext->event.count; ++i) {
+ events = image_g_new0 (image, MonoEvent, ext->event.count);
+ ext->events = events;
+ for (i = 0; i < ext->event.count; ++i) {
eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
events [i].parent = klass;
events [i].attrs = eb->attrs;
MonoClass *inst_klass = mono_class_from_mono_type (type);
//Ensure it's safe to use it.
if (!fix_partial_generic_class (inst_klass, error)) {
- mono_class_set_failure (inst_klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (inst_klass, "Could not initialized generic type instance due to: %s", mono_error_get_message (error));
// Marked the class with failure, but since some other instantiation already failed,
// just report that one, and swallow the error from this one.
if (already_failed)
mono_error_init (&error);
+ 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);
* Fields to set in klass:
* the various flags: delegate/unicode/contextbound etc.
*/
- klass->flags = tb->attrs;
+ mono_class_set_flags (klass, tb->attrs);
klass->has_cctor = 1;
mono_class_setup_parent (klass, klass->parent);
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));
+ mono_class_get_ext (klass)->nested_classes = g_list_prepend_image (klass->image, mono_class_get_ext (klass)->nested_classes, mono_class_from_mono_type (subtype));
}
}
klass->nested_classes_inited = TRUE;
- /* fields and object layout */
- if (klass->parent) {
- if (!klass->parent->size_inited)
- mono_class_init (klass->parent);
- klass->instance_size = klass->parent->instance_size;
- klass->sizes.class_size = 0;
- klass->min_align = klass->parent->min_align;
- /* if the type has no fields we won't call the field_setup
- * routine which sets up klass->has_references.
- */
- klass->has_references |= klass->parent->has_references;
- } else {
- klass->instance_size = sizeof (MonoObject);
- klass->min_align = 1;
- }
-
- /* FIXME: handle packing_size and instance_size */
typebuilder_setup_fields (klass, &error);
if (!mono_error_ok (&error))
goto failure;
klass->wastypebuilder = TRUE;
+ if (tb->generic_params) {
+ for (i = 0; i < mono_array_length (tb->generic_params); i++) {
+ MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
+ MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, &error);
+ MonoClass *gklass = mono_class_from_mono_type (param_type);
+
+ gklass->wastypebuilder = TRUE;
+ }
+ }
+
/*
* 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,
*
* Together with this we must ensure the contents of all instances to match the created type.
*/
- if (domain->type_hash && klass->generic_container) {
+ if (domain->type_hash && mono_class_is_gtd (klass)) {
struct remove_instantiations_user_data data;
data.klass = klass;
data.error = &error;
mono_loader_unlock ();
if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "Not a valid enumeration");
mono_error_set_type_load_class (&error, klass, "Not a valid enumeration");
goto failure_unlocked;
}
return res;
failure:
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_type_load_failure (klass, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (&error));
klass->wastypebuilder = TRUE;
mono_domain_unlock (domain);
mono_loader_unlock ();
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;
//g_assert (klass->wastypebuilder);
}
- if (klass->generic_class) {
- MonoGenericInst *inst = klass->generic_class->context.class_inst;
+ if (mono_class_is_ginst (klass)) {
+ MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
int i;
for (i = 0; i < inst->type_argc; ++i) {
return NULL;
}
-void
-ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb)
-{
- g_assert_not_reached ();
-}
-
-gboolean
-mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error)
-{
- g_assert_not_reached ();
- return FALSE;
-}
-
void
mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
{
return NULL;
}
-void
-ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
-{
- g_assert_not_reached ();
-}
-
void
ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb)
{
#endif /* DISABLE_REFLECTION_EMIT */
-#ifndef DISABLE_REFLECTION_EMIT
-MonoMethod*
-mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
-{
- MonoType *tb;
- MonoClass *klass;
-
- tb = mono_reflection_type_get_handle ((MonoReflectionType*)mb->type, error);
- return_val_if_nok (error, NULL);
- klass = mono_class_from_mono_type (tb);
-
- return methodbuilder_to_mono_method (klass, mb, error);
-}
-#else /* DISABLE_REFLECTION_EMIT */
-MonoMethod*
-mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error)
+void
+mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
{
- g_assert_not_reached ();
- return NULL;
+ mono_gc_deregister_root ((char*) &entry->gparam);
+ g_free (entry);
}
-#endif /* DISABLE_REFLECTION_EMIT */
gint32
ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
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)