-/*
- * sre.c: Routines for creating an image at runtime
- * and related System.Reflection.Emit icalls
+/**
+ * \file
+ * Routines for creating an image at runtime
+ * and related System.Reflection.Emit icalls
*
*
* Author:
#include "mono/utils/mono-digest.h"
#include "mono/utils/w32api.h"
-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 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 char* string_to_utf8_image_raw (MonoImage *image, MonoString *s, MonoError *error);
#ifndef DISABLE_REFLECTION_EMIT
-static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error);
static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError *error);
static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb);
static gboolean reflection_setup_internal_class (MonoReflectionTypeBuilderHandle tb, MonoError *error);
-static gboolean reflection_create_generic_class (MonoReflectionTypeBuilderHandle tb, MonoError *error);
+static gboolean reflection_init_generic_class (MonoReflectionTypeBuilderHandle tb, MonoError *error);
+static gboolean reflection_setup_class_hierarchy (GHashTable *unparented, MonoError *error);
static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
/* FIXME all callers to string_to_utf8_image_raw should use handles */
HANDLE_FUNCTION_ENTER ();
char* result = NULL;
- mono_error_init (error);
+ error_init (error);
MONO_HANDLE_DCL (MonoString, s);
result = mono_string_to_utf8_image (image, s, error);
HANDLE_FUNCTION_RETURN_VAL (result);
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
MonoExceptionClause *clauses;
MonoExceptionClause *clause;
mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
mono_loader_unlock ();
+}
+#else
+//FIXME some code compiled under DISABLE_REFLECTION_EMIT depends on this function, we should be more aggressively disabling things
+static void
+mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
+{
}
#endif
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
memset (rmb, 0, sizeof (ReflectionMethodBuilder));
rmb->ilgen = mb->ilgen;
const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
- mono_error_init (error);
+ error_init (error);
memset (rmb, 0, sizeof (ReflectionMethodBuilder));
rmb->call_conv = mb->call_conv;
rmb->code = NULL;
rmb->type = mb->type;
- rmb->name = mono_string_new (mono_domain_get (), name);
+ rmb->name = mono_string_new_checked (mono_domain_get (), name, error);
+ return_val_if_nok (error, FALSE);
rmb->table_idx = &mb->table_idx;
rmb->init_locals = mb->init_locals;
rmb->skip_visibility = FALSE;
}
-static guint32
+guint32
mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
{
MONO_REQ_GC_NEUTRAL_MODE;
return token;
}
+#else /* DISABLE_REFLECTION_EMIT */
+
+guint32
+mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
+{
+ g_assert_not_reached ();
+ return -1;
+}
#endif
static gboolean
#ifndef DISABLE_REFLECTION_EMIT
static guint32
-mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObjectHandle f, MonoClassField *field)
+mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoClassField *field)
{
MonoType *type;
guint32 token;
g_assert (field);
g_assert (field->parent);
- token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, MONO_HANDLE_RAW (f)));
+ token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, field));
if (token)
return token;
token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
mono_field_get_name (field),
mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, type));
- mono_g_hash_table_insert (assembly->handleref_managed, MONO_HANDLE_RAW (f), GUINT_TO_POINTER(token));
+ g_hash_table_insert (assembly->handleref, field, GUINT_TO_POINTER(token));
return token;
}
MonoDynamicTable *table;
guint32 *values;
- mono_error_init (error);
+ error_init (error);
table = &assembly->tables [MONO_TABLE_STANDALONESIG];
idx = table->next_idx ++;
MonoMethodSignature *sig = NULL;
char *name = NULL;
- mono_error_init (error);
+ error_init (error);
MonoArrayHandle parameters = MONO_HANDLE_NEW_GET (MonoArray, m, parameters);
guint32 nparams = mono_array_handle_length (parameters);
}
token = MONO_TOKEN_STRING | idx;
- mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, str));
+ mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, str), MONO_DYN_IMAGE_TOK_NEW);
leave:
HANDLE_FUNCTION_RETURN_VAL (token);
{
guint32 token = 0;
- mono_error_init (error);
+ error_init (error);
MonoClass *klass = mono_handle_class (obj);
if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
g_error ("requested method token for %s\n", klass->name);
}
- mono_dynamic_image_register_token (assembly, token, obj);
+ mono_dynamic_image_register_token (assembly, token, obj, MONO_DYN_IMAGE_TOK_NEW);
return token;
fail:
g_assert (!mono_error_ok (error));
gboolean create_open_instance, gboolean register_token,
MonoError *error)
{
+ HANDLE_FUNCTION_ENTER ();
guint32 token = 0;
- mono_error_init (error);
+ error_init (error);
MonoClass *klass = mono_handle_class (obj);
+ MonoObjectHandle register_obj = MONO_HANDLE_NEW (MonoObject, NULL);
+ MONO_HANDLE_ASSIGN (register_obj, obj);
/* Check for user defined reflection objects */
/* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
- return 0;
+ goto leave;
}
+ /* This function is called from ModuleBuilder:getToken multiple times for the same objects */
+ int how_collide = MONO_DYN_IMAGE_TOK_SAME_OK;
+
if (strcmp (klass->name, "RuntimeType") == 0) {
MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, obj), error);
- return_val_if_nok (error, 0);
+ if (!is_ok (error))
+ goto leave;
MonoClass *mc = mono_class_from_mono_type (type);
token = mono_metadata_token_from_dor (
mono_dynimage_encode_typedef_or_ref_full (assembly, type, !mono_class_is_gtd (mc) || create_open_instance));
+ /* If it's a RuntimeType now, we could have registered a
+ * TypeBuilder for it before, so replacing is okay. */
+ how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
} else if (strcmp (klass->name, "MonoCMethod") == 0 ||
strcmp (klass->name, "MonoMethod") == 0) {
MonoReflectionMethodHandle m = MONO_HANDLE_CAST (MonoReflectionMethod, obj);
* FIXME: do the equivalent for Fields.
*/
token = method->token;
+ how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
} else {
/*
* Each token should have a unique index, but the indexes are
*/
method_table_idx --;
token = MONO_TOKEN_METHOD_DEF | method_table_idx;
+ how_collide = MONO_DYN_IMAGE_TOK_NEW;
}
} else {
- token = mono_image_get_methodref_token (assembly, method, create_open_instance);
+ guint32 methodref_token = mono_image_get_methodref_token (assembly, method, create_open_instance);
+ /* We need to register a 'canonical' object. The same
+ * MonoMethod could have been reflected via different
+ * classes so the MonoReflectionMethod:reftype could be
+ * different, and the object lookup in
+ * dynamic_image_register_token would assert assert. So
+ * we pick the MonoReflectionMethod object that has the
+ * reflected type as NULL (ie, take the declaring type
+ * of the method) */
+ MonoReflectionMethodHandle canonical_obj =
+ mono_method_get_object_handle (MONO_HANDLE_DOMAIN (obj), method, NULL, error);
+ if (!is_ok (error))
+ goto leave;
+ MONO_HANDLE_ASSIGN (register_obj, canonical_obj);
+ token = methodref_token;
}
/*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
} else if (strcmp (klass->name, "MonoField") == 0) {
static guint32 field_table_idx = 0xffffff;
field_table_idx --;
token = MONO_TOKEN_FIELD_DEF | field_table_idx;
+ how_collide = MONO_DYN_IMAGE_TOK_NEW;
} else {
- token = mono_image_get_fieldref_token (assembly, obj, field);
+ guint32 fieldref_token = mono_image_get_fieldref_token (assembly, field);
+ /* Same as methodref: get a canonical object to
+ * register with the token. */
+ MonoReflectionFieldHandle canonical_obj =
+ mono_field_get_object_handle (MONO_HANDLE_DOMAIN (obj), field->parent, field, error);
+ if (!is_ok (error))
+ goto leave;
+ MONO_HANDLE_ASSIGN (register_obj, canonical_obj);
+ token = fieldref_token;
}
/*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
} else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
MonoReflectionArrayMethodHandle m = MONO_HANDLE_CAST (MonoReflectionArrayMethod, obj);
- token = mono_image_get_array_token (assembly, m, error);
- return_val_if_nok (error, 0);
+ /* always returns a fresh token */
+ guint32 array_token = mono_image_get_array_token (assembly, m, error);
+ if (!is_ok (error))
+ goto leave;
+ token = array_token;
+ how_collide = MONO_DYN_IMAGE_TOK_NEW;
} else if (strcmp (klass->name, "SignatureHelper") == 0) {
MonoReflectionSigHelperHandle s = MONO_HANDLE_CAST (MonoReflectionSigHelper, obj);
- token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
- return_val_if_nok (error, 0);
- } else if (strcmp (klass->name, "EnumBuilder") == 0) {
- MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, obj), error);
- return_val_if_nok (error, 0);
- token = mono_metadata_token_from_dor (
- mono_image_typedef_or_ref (assembly, type));
+ /* always returns a fresh token */
+ guint32 sig_token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
+ if (!is_ok (error))
+ goto leave;
+ token = sig_token;
+ how_collide = MONO_DYN_IMAGE_TOK_NEW;
} else {
g_error ("requested token for %s\n", klass->name);
}
if (register_token)
- mono_dynamic_image_register_token (assembly, token, obj);
+ mono_dynamic_image_register_token (assembly, token, register_obj, how_collide);
- return token;
+leave:
+ HANDLE_FUNCTION_RETURN_VAL (token);
}
#ifndef DISABLE_REFLECTION_EMIT
+static gboolean
+assemblybuilderaccess_can_refonlyload (guint32 access)
+{
+ return (access & 0x4) != 0;
+}
+
+static gboolean
+assemblybuilderaccess_can_run (guint32 access)
+{
+ return (access & MonoAssemblyBuilderAccess_Run) != 0;
+}
+
+static gboolean
+assemblybuilderaccess_can_save (guint32 access)
+{
+ return (access & MonoAssemblyBuilderAccess_Save) != 0;
+}
+
+
/*
* mono_reflection_dynimage_basic_init:
* @assembly: an assembly builder object
if (assemblyb->dynamic_assembly)
return;
-#if HAVE_BOEHM_GC
- /* assembly->assembly.image might be GC allocated */
- assembly = assemblyb->dynamic_assembly = (MonoDynamicAssembly *)GC_MALLOC (sizeof (MonoDynamicAssembly));
-#else
assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
-#endif
- mono_profiler_assembly_event (&assembly->assembly, MONO_PROFILE_START_LOAD);
+ MONO_PROFILER_RAISE (assembly_loading, (&assembly->assembly));
assembly->assembly.ref_count = 1;
assembly->assembly.dynamic = TRUE;
assembly->assembly.aname.revision = 0;
}
- assembly->run = assemblyb->access != 2;
- assembly->save = assemblyb->access != 1;
+ assembly->assembly.ref_only = assemblybuilderaccess_can_refonlyload (assemblyb->access);
+ assembly->run = assemblybuilderaccess_can_run (assemblyb->access);
+ assembly->save = assemblybuilderaccess_can_save (assemblyb->access);
assembly->domain = domain;
char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
- mono_profiler_assembly_loaded (&assembly->assembly, MONO_PROFILE_OK);
+ MONO_PROFILER_RAISE (assembly_loaded, (&assembly->assembly));
mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
}
static gboolean
image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
MonoDomain *domain = MONO_HANDLE_DOMAIN (moduleb);
MonoDynamicImage *image = MONO_HANDLE_GETVAL (moduleb, dynamic_image);
MonoReflectionAssemblyBuilderHandle ab = MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder, NULL);
static gboolean
mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
return image_module_basic_init (moduleb, error);
}
mono_type_array_get_and_resolve (MonoArrayHandle array, int idx, MonoError *error)
{
HANDLE_FUNCTION_ENTER();
- mono_error_init (error);
+ error_init (error);
MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
MONO_HANDLE_ARRAY_GETREF (t, array, idx);
MonoType *result = mono_reflection_type_handle_mono_type (t, error);
static MonoMethod *method_get_underlying_system_type = NULL;
HANDLE_FUNCTION_ENTER ();
- mono_error_init (error);
+ error_init (error);
if (!method_get_underlying_system_type)
method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
mono_reflection_type_get_handle (MonoReflectionType* ref_raw, MonoError *error)
{
HANDLE_FUNCTION_ENTER ();
- mono_error_init (error);
+ error_init (error);
MONO_HANDLE_DCL (MonoReflectionType, ref);
MonoType *result = mono_reflection_type_handle_mono_type (ref, error);
HANDLE_FUNCTION_RETURN_VAL (result);
}
MonoClass *gtd_klass = mono_class_from_mono_type (gtd);
if (is_sre_type_builder (mono_handle_class (ref_gtd))) {
- reflection_create_generic_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_gtd), error);
+ reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_gtd), error);
if (!is_ok (error)) {
goto leave;
}
reflection_param_handle_mono_type (MonoReflectionGenericParamHandle ref_gparam, MonoError *error)
{
HANDLE_FUNCTION_ENTER ();
- mono_error_init (error);
+ error_init (error);
MonoType *result = NULL;
mono_type_array_get_and_resolve_raw (MonoArray* array_raw, int idx, MonoError *error)
{
HANDLE_FUNCTION_ENTER(); /* FIXME callers of mono_type_array_get_and_resolve_raw should use handles */
- mono_error_init (error);
+ error_init (error);
MONO_HANDLE_DCL (MonoArray, array);
MonoType *result = mono_type_array_get_and_resolve (array, idx, error);
HANDLE_FUNCTION_RETURN_VAL (result);
mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error)
{
HANDLE_FUNCTION_ENTER ();
- mono_error_init (error);
+ error_init (error);
MonoType* result = NULL;
goto leave;
g_assert (base);
gint32 rank = MONO_HANDLE_GETVAL (sre_array, rank);
- if (rank == 0) //single dimentional array
- result = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
- else
- result = &mono_bounded_array_class_get (mono_class_from_mono_type (base), rank, TRUE)->byval_arg;
+ MonoClass *eclass = mono_class_from_mono_type (base);
+ result = mono_image_new0 (eclass->image, MonoType, 1);
+ if (rank == 0) {
+ result->type = MONO_TYPE_SZARRAY;
+ result->data.klass = eclass;
+ } else {
+ MonoArrayType *at = (MonoArrayType *)mono_image_alloc0 (eclass->image, sizeof (MonoArrayType));
+ result->type = MONO_TYPE_ARRAY;
+ result->data.array = at;
+ at->eklass = eclass;
+ at->rank = rank;
+ }
MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
} else if (is_sre_byref (klass)) {
MonoReflectionDerivedTypeHandle sre_byref = MONO_HANDLE_CAST (MonoReflectionDerivedType, ref);
MonoMethodSignature *sig;
int count, i;
- mono_error_init (error);
+ error_init (error);
count = MONO_HANDLE_IS_NULL (parameters) ? 0 : mono_array_handle_length (parameters);
ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilderHandle ctor, MonoError *error) {
MonoMethodSignature *sig;
- mono_error_init (error);
+ error_init (error);
sig = parameters_to_signature (image, MONO_HANDLE_NEW_GET (MonoArray, ctor, parameters), error);
return_val_if_nok (error, NULL);
method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilderHandle method, MonoError *error) {
MonoMethodSignature *sig;
- mono_error_init (error);
+ error_init (error);
sig = parameters_to_signature (image, MONO_HANDLE_NEW_GET(MonoArray, method, parameters), error);
return_val_if_nok (error, NULL);
HANDLE_FUNCTION_ENTER ();
MonoMethodSignature *sig = NULL;
- mono_error_init (error);
+ error_init (error);
sig = parameters_to_signature (NULL, MONO_HANDLE_NEW_GET (MonoArray, method, parameters), error);
if (!is_ok (error))
static void
get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
MonoClass *klass = mono_object_class (prop);
if (strcmp (klass->name, "PropertyBuilder") == 0) {
MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
static void
get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
MonoClass *klass = mono_object_class (field);
if (strcmp (klass->name, "FieldBuilder") == 0) {
MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
{
MonoTypeEnum simple_type;
- mono_error_init (error);
+ error_init (error);
if ((p-buffer) + 10 >= *buflen) {
char *newbuf;
*buflen *= 2;
{
int len;
- mono_error_init (error);
+ error_init (error);
/* Preallocate a large enough buffer */
if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
/**
* mono_reflection_get_custom_attrs_blob:
- * @ctor: custom attribute constructor
- * @ctorArgs: arguments o the constructor
- * @properties:
- * @propValues:
- * @fields:
- * @fieldValues:
- *
+ * \param ctor custom attribute constructor
+ * \param ctorArgs arguments o the constructor
+ * \param properties
+ * \param propValues
+ * \param fields
+ * \param fieldValues
* Creates the blob of data that needs to be saved in the metadata and that represents
- * the custom attributed described by @ctor, @ctorArgs etc.
- * Returns: a Byte array representing the blob of data.
+ * the custom attributed described by \p ctor, \p ctorArgs etc.
+ * \returns a \c Byte array representing the blob of data.
*/
MonoArray*
mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
/**
* mono_reflection_get_custom_attrs_blob_checked:
- * @ctor: custom attribute constructor
- * @ctorArgs: arguments o the constructor
- * @properties:
- * @propValues:
- * @fields:
- * @fieldValues:
- * @error: set on error
- *
+ * \param ctor custom attribute constructor
+ * \param ctorArgs arguments o the constructor
+ * \param properties
+ * \param propValues
+ * \param fields
+ * \param fieldValues
+ * \param error set on error
* Creates the blob of data that needs to be saved in the metadata and that represents
- * the custom attributed described by @ctor, @ctorArgs etc.
- * Returns: a Byte array representing the blob of data. On failure returns NULL and sets @error.
+ * the custom attributed described by \p ctor, \p ctorArgs etc.
+ * \returns a \c Byte array representing the blob of data. On failure returns NULL and sets \p error.
*/
MonoArray*
mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error)
char *buffer, *p;
guint32 buflen, i;
- mono_error_init (error);
+ error_init (error);
if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
/* sig is freed later so allocate it in the heap */
return result;
}
-/**
- * reflection_setup_internal_class:
- * @tb: a TypeBuilder object
- * @error: set on error
- *
- * 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).
- *
- * Returns TRUE on success. On failure, returns FALSE and sets @error.
- */
static gboolean
-reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
+reflection_setup_class_hierarchy (GHashTable *unparented, MonoError *error)
{
- HANDLE_FUNCTION_ENTER ();
- mono_error_init (error);
+ error_init (error);
mono_loader_lock ();
- MonoReflectionTypeHandle ref_parent = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_tb, parent);
- MonoClass *parent = NULL;
- if (!MONO_HANDLE_IS_NULL (ref_parent)) {
- MonoType *parent_type = mono_reflection_type_handle_mono_type (ref_parent, error);
- if (!is_ok (error))
- goto leave;
- /* check so we can compile corlib correctly */
- if (strcmp (mono_handle_class (ref_parent)->name, "TypeBuilder") == 0) {
- /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
- parent = parent_type->data.klass;
- } else {
- parent = mono_class_from_mono_type (parent_type);
+ MonoType *parent_type;
+ MonoType *child_type;
+ GHashTableIter iter;
+
+ g_hash_table_iter_init (&iter, unparented);
+
+ while (g_hash_table_iter_next (&iter, (gpointer *) &child_type, (gpointer *) &parent_type)) {
+ MonoClass *child_class = mono_class_from_mono_type (child_type);
+ if (parent_type != NULL) {
+ MonoClass *parent_class = mono_class_from_mono_type (parent_type);
+ child_class->parent = NULL;
+ /* fool mono_class_setup_parent */
+ child_class->supertypes = NULL;
+ mono_class_setup_parent (child_class, parent_class);
+ } else if (strcmp (child_class->name, "Object") == 0 && strcmp (child_class->name_space, "System") == 0) {
+ const char *old_n = child_class->name;
+ /* trick to get relative numbering right when compiling corlib */
+ child_class->name = "BuildingObject";
+ mono_class_setup_parent (child_class, mono_defaults.object_class);
+ child_class->name = old_n;
}
+ mono_class_setup_mono_type (child_class);
+ mono_class_setup_supertypes (child_class);
}
-
- /* the type has already being created: it means we just have to change the parent */
- MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
- if (type != NULL) {
- MonoClass *klass = mono_class_from_mono_type (type);
- klass->parent = NULL;
- /* fool mono_class_setup_parent */
- klass->supertypes = NULL;
- mono_class_setup_parent (klass, parent);
- mono_class_setup_mono_type (klass);
+
+ mono_loader_unlock ();
+ return is_ok (error);
+}
+
+static gboolean
+reflection_setup_internal_class_internal (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
+{
+ HANDLE_FUNCTION_ENTER ();
+ error_init (error);
+
+ mono_loader_lock ();
+
+ gint32 entering_state = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_tb), state);
+ if (entering_state != MonoTypeBuilderNew) {
+ g_assert (MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type));
goto leave;
}
+ MONO_HANDLE_SETVAL (ref_tb, state, MonoTypeBuilderState, MonoTypeBuilderEntered);
+ MonoReflectionModuleBuilderHandle module_ref = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
+ GHashTable *unparented_classes = MONO_HANDLE_GETVAL(module_ref, unparented_classes);
+
+ // If this type is already setup, exit. We'll fix the parenting later
+ MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
+ if (type)
+ goto leave;
+
MonoReflectionModuleBuilderHandle ref_module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
klass->type_token = MONO_TOKEN_TYPE_DEF | table_idx;
mono_class_set_flags (klass, MONO_HANDLE_GETVAL (ref_tb, attrs));
- mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
+ MONO_PROFILER_RAISE (class_loading, (klass));
klass->element_class = klass;
*/
mono_image_append_class_to_reflection_info_set (klass);
- mono_dynamic_image_register_token (dynamic_image, MONO_TOKEN_TYPE_DEF | table_idx, MONO_HANDLE_CAST (MonoObject, ref_tb));
-
- if (parent != NULL) {
- mono_class_setup_parent (klass, parent);
- } else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
- const char *old_n = klass->name;
- /* trick to get relative numbering right when compiling corlib */
- klass->name = "BuildingObject";
- mono_class_setup_parent (klass, mono_defaults.object_class);
- klass->name = old_n;
- }
+ mono_dynamic_image_register_token (dynamic_image, MONO_TOKEN_TYPE_DEF | table_idx, MONO_HANDLE_CAST (MonoObject, ref_tb), MONO_DYN_IMAGE_TOK_NEW);
if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
(!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
mono_class_setup_mono_type (klass);
- mono_class_setup_supertypes (klass);
-
/*
* FIXME: handle interfaces.
*/
-
MonoReflectionTypeHandle ref_tb_type = MONO_HANDLE_CAST (MonoReflectionType, ref_tb);
MONO_HANDLE_SETVAL (ref_tb_type, type, MonoType*, &klass->byval_arg);
+ MONO_HANDLE_SETVAL (ref_tb, state, gint32, MonoTypeBuilderFinished);
+
+ reflection_init_generic_class (ref_tb, error);
+ if (!is_ok (error))
+ goto leave;
+
+ // Do here so that the search inside of the parent can see the above type that's been set.
+ MonoReflectionTypeHandle ref_parent = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_tb, parent);
+ MonoType *parent_type = NULL;
+ if (!MONO_HANDLE_IS_NULL (ref_parent)) {
+ MonoClass *parent_klass = mono_handle_class (ref_parent);
+ gboolean recursive_init = TRUE;
+
+ if (is_sre_type_builder (parent_klass)) {
+ MonoTypeBuilderState parent_state = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_parent), state);
+
+ if (parent_state != MonoTypeBuilderNew) {
+ // Initialize types reachable from parent recursively
+ // We'll fix the type hierarchy later
+ recursive_init = FALSE;
+ }
+ }
+
+ if (recursive_init) {
+ // If we haven't encountered a cycle, force the creation of ref_parent's type
+ mono_reflection_type_handle_mono_type (ref_parent, error);
+ if (!is_ok (error))
+ goto leave;
+ }
+
+ parent_type = MONO_HANDLE_GETVAL (ref_parent, type);
+
+ // If we failed to create the parent, fail the child
+ if (!parent_type)
+ goto leave;
+ }
+
+ // Push the child type and parent type to process later
+ // Note: parent_type may be null.
+ g_assert (!g_hash_table_lookup (unparented_classes, &klass->byval_arg));
+ g_hash_table_insert (unparented_classes, &klass->byval_arg, parent_type);
if (!MONO_HANDLE_IS_NULL (ref_nesting_type)) {
if (!reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_nesting_type), error))
/*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
- mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
+ MONO_PROFILER_RAISE (class_loaded, (klass));
leave:
mono_loader_unlock ();
}
/**
- * reflection_create_generic_class:
+ * reflection_init_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.
+ *
+ * This assumes that reflection_setup_internal_class has already set up
+ * ref_tb
*/
static gboolean
-reflection_create_generic_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
+reflection_init_generic_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
{
HANDLE_FUNCTION_ENTER ();
- mono_error_init (error);
+ error_init (error);
- reflection_setup_internal_class (ref_tb, error);
- if (!is_ok (error))
- goto leave;
+ MonoTypeBuilderState ref_state = MONO_HANDLE_GETVAL (ref_tb, state);
+ g_assert (ref_state == MonoTypeBuilderFinished);
MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
MonoClass *klass = mono_class_from_mono_type (type);
}
generic_container->context.class_inst = mono_get_shared_generic_inst (generic_container);
+ MonoGenericContext* context = &generic_container->context;
+ MonoType *canonical_inst = &((MonoClassGtd*)klass)->canonical_inst;
+ canonical_inst->type = MONO_TYPE_GENERICINST;
+ canonical_inst->data.generic_class = mono_metadata_lookup_generic_class (klass, context->class_inst, FALSE);
+
leave:
HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
}
{
MonoMarshalSpec *res;
- mono_error_init (error);
+ error_init (error);
res = image_g_new0 (image, MonoMarshalSpec, 1);
res->native = (MonoMarshalNative)minfo->type;
mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
MonoMarshalSpec *spec, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
MonoReflectionMarshalAsAttributeHandle minfo = MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error));
if (!is_ok (error))
gboolean dynamic;
int i;
- mono_error_init (error);
+ error_init (error);
/*
* Methods created using a MethodBuilder should have their memory allocated
* inside the image mempool, while dynamic methods should have their memory
(rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
else
- m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
+ m = (MonoMethod *)image_g_new0 (image, MonoDynamicMethod, 1);
wrapperm = (MonoMethodWrapper*)m;
}
wrapperm->header = header;
+ MonoDynamicMethod *dm = (MonoDynamicMethod*)wrapperm;
+ dm->assembly = klass->image->assembly;
}
if (rmb->generic_params) {
ReflectionMethodBuilder rmb;
MonoMethodSignature *sig;
- mono_error_init (error);
+ error_init (error);
mono_loader_lock ();
methodbuilder_to_mono_method_raw (MonoClass *klass, MonoReflectionMethodBuilder* mb_raw, MonoError *error)
{
HANDLE_FUNCTION_ENTER (); /* FIXME change callers of methodbuilder_to_mono_method_raw to use handles */
- mono_error_init (error);
+ error_init (error);
MONO_HANDLE_DCL (MonoReflectionMethodBuilder, mb);
MonoMethod *result = methodbuilder_to_mono_method (klass, mb, error);
HANDLE_FUNCTION_RETURN_VAL (result);
MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
int i;
- mono_error_init (error);
+ error_init (error);
if (klass->wastypebuilder)
return TRUE;
{
MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
- mono_error_init (error);
+ error_init (error);
if (!ensure_runtime_vtable (gklass, error))
return FALSE;
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
int i, num, j;
- mono_error_init (error);
+ error_init (error);
if (!image_is_dynamic (klass->image) || (!tb && !mono_class_is_ginst (klass)) || klass->wastypebuilder)
return TRUE;
static MonoMethod*
mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
MonoClass *klass = mono_object_class (method);
if (is_sr_mono_method (klass)) {
MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
int i, j, onum;
MonoReflectionMethod *m;
- mono_error_init (error);
+ error_init (error);
*overrides = NULL;
*num_overrides = 0;
int fcount = tb->num_fields;
mono_class_set_field_count (klass, fcount);
- mono_error_init (error);
+ error_init (error);
if (tb->class_size) {
packing_size = tb->packing_size;
return_if_nok (error);
}
+ if (!klass->enumtype && !mono_type_get_underlying_type (field->type)) {
+ mono_class_set_type_load_failure (klass, "Field '%s' is an enum type with a bad underlying type", field->name);
+ continue;
+ }
+
if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
char *base = mono_array_addr (rva_data, char, 0);
size_t size = mono_array_length (rva_data);
}
}
- mono_class_layout_fields (klass, instance_size, packing_size, TRUE);
+ if (!mono_class_has_failure (klass)) {
+ mono_class_layout_fields (klass, instance_size, packing_size, TRUE);
+ }
}
static void
MonoClassPropertyInfo *info;
int i;
- mono_error_init (error);
+ error_init (error);
info = mono_class_get_property_info (klass);
if (!info) {
MonoClassEventInfo *info;
int i;
- mono_error_init (error);
+ error_init (error);
info = mono_class_alloc0 (klass, sizeof (MonoClassEventInfo));
mono_class_set_event_info (klass, info);
return FALSE;
}
+/**
+ * reflection_setup_internal_class:
+ * @tb: a TypeBuilder object
+ * @error: set on error
+ *
+ * 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).
+ *
+ * Returns TRUE on success. On failure, returns FALSE and sets @error.
+ */
+static gboolean
+reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
+{
+ MonoReflectionModuleBuilderHandle module_ref = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
+ GHashTable *unparented_classes = MONO_HANDLE_GETVAL(module_ref, unparented_classes);
+
+ if (unparented_classes) {
+ return reflection_setup_internal_class_internal (ref_tb, error);
+ } else {
+ // If we're not being called recursively
+ unparented_classes = g_hash_table_new (NULL, NULL);
+ MONO_HANDLE_SETVAL (module_ref, unparented_classes, GHashTable *, unparented_classes);
+
+ gboolean ret_val = reflection_setup_internal_class_internal (ref_tb, error);
+ mono_error_assert_ok (error);
+
+ // Fix the relationship between the created classes and their parents
+ reflection_setup_class_hierarchy (unparented_classes, error);
+ mono_error_assert_ok (error);
+
+ g_hash_table_destroy (unparented_classes);
+ MONO_HANDLE_SETVAL (module_ref, unparented_classes, GHashTable *, NULL);
+
+ return ret_val;
+ }
+}
+
+
MonoReflectionTypeHandle
ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
- reflection_create_generic_class (ref_tb, error);
+ reflection_setup_internal_class (ref_tb, error);
mono_error_assert_ok (error);
MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_tb);
GSList *l;
int i;
- mono_error_init (error);
+ error_init (error);
if (mono_runtime_is_shutting_down ()) {
mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
rmb.refs [i + 1] = handle_class;
}
+ MonoAssembly *ass = NULL;
if (mb->owner) {
MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
if (!is_ok (error)) {
return FALSE;
}
klass = mono_class_from_mono_type (owner_type);
+ ass = klass->image->assembly;
} else {
klass = mono_defaults.object_class;
+ ass = (mb->module && mb->module->image) ? mb->module->image->assembly : NULL;
}
mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
+ ((MonoDynamicMethod*)handle)->assembly = ass;
g_free (rmb.refs);
return_val_if_nok (error, FALSE);
MonoMethodSignature *sig;
g_assert (image_is_dynamic (image));
- mono_error_init (error);
+ error_init (error);
sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
if (sig)
static void
ensure_complete_type (MonoClass *klass, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_has_ref_info (klass)) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
MonoClass *oklass = obj->vtable->klass;
gpointer result = NULL;
- mono_error_init (error);
+ error_init (error);
if (strcmp (oklass->name, "String") == 0) {
result = mono_string_intern_checked ((MonoString*)obj, error);
void
mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
*overrides = NULL;
*num_overrides = 0;
}
void
ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
}
MonoType*
mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
if (!ref)
return NULL;
return ref->type;
MonoType*
mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
if (MONO_HANDLE_IS_NULL (ref))
return NULL;
return MONO_HANDLE_GETVAL (ref, type);
void
mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
{
- mono_gc_deregister_root ((char*) &entry->gparam);
+ MONO_GC_UNREGISTER_ROOT_IF_MOVING (entry->gparam);
g_free (entry);
}
gint32
ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, gboolean create_open_instance, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
if (MONO_HANDLE_IS_NULL (obj)) {
mono_error_set_argument_null (error, "obj", "");
return 0;
MonoArrayHandle opt_param_types,
MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
if (MONO_HANDLE_IS_NULL (method)) {
mono_error_set_argument_null (error, "method", "");
return 0;
void
ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, guint32 token, MonoError *error)
{
- mono_error_init (error);
- mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb, dynamic_image), token, obj);
+ error_init (error);
+ /* This function may be called by ModuleBuilder.FixupTokens to update
+ * an existing token, so replace is okay here. */
+ mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb, dynamic_image), token, obj, MONO_DYN_IMAGE_TOK_REPLACE);
}
-MonoObject*
-ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
+MonoObjectHandle
+ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilderHandle mb, guint32 token, MonoError *error)
{
- MonoObject *obj;
-
- mono_loader_lock ();
- obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
- mono_loader_unlock ();
-
- return obj;
+ error_init (error);
+ MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (mb, dynamic_image);
+ return mono_dynamic_image_get_registered_token (dynamic_image, token, error);
}
#ifndef DISABLE_REFLECTION_EMIT
}
void
-ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
- MonoReflectionType *t)
+ves_icall_AssemblyBuilder_UpdateNativeCustomAttributes (MonoReflectionAssemblyBuilderHandle assemblyb, MonoError *error)
{
- enumtype->type = t->type;
+ MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, assemblyb, cattrs);
+
+ MonoReflectionAssemblyHandle assembly_handle = MONO_HANDLE_CAST (MonoReflectionAssembly, assemblyb);
+ MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
+ g_assert (assembly);
+
+ mono_save_custom_attrs (assembly->image, assembly, MONO_HANDLE_RAW (cattrs));
+}
+
+void
+ves_icall_EnumBuilder_setup_enum_type (MonoReflectionTypeHandle enumtype,
+ MonoReflectionTypeHandle t,
+ MonoError *error)
+{
+ error_init (error);
+ MONO_HANDLE_SETVAL (enumtype, type, MonoType*, MONO_HANDLE_GETVAL (t, type));
}
void
ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
mono_image_module_basic_init (moduleb, error);
}
}
void
-ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
+ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilderHandle moduleb, MonoReflectionTypeHandle ref_type, MonoError *error)
{
- MonoDynamicImage *image = moduleb->dynamic_image;
+ error_init (error);
+ MonoDynamicImage *image = MONO_HANDLE_GETVAL (moduleb, dynamic_image);
+ MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
- g_assert (type->type);
- image->wrappers_type = mono_class_from_mono_type (type->type);
+ g_assert (type);
+ image->wrappers_type = mono_class_from_mono_type (type);
}