X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fsre.c;h=b899c830e7898d960ad8418a4afb49c70ef2b882;hb=651161fa9d2fc5e1cacdbf58e244f759e879f317;hp=fbde1f1cc0fd3e00e6281d61ab0b514512a03609;hpb=3ab1a56f73cac926676e24b58d07bf0c4e75d3eb;p=mono.git diff --git a/mono/metadata/sre.c b/mono/metadata/sre.c index fbde1f1cc0f..b899c830e78 100644 --- a/mono/metadata/sre.c +++ b/mono/metadata/sre.c @@ -1,6 +1,7 @@ -/* - * 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: @@ -42,12 +43,12 @@ static GENERATE_GET_CLASS_WITH_CACHE (module_builder, "System.Reflection.Emit", 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); @@ -90,7 +91,7 @@ string_to_utf8_image_raw (MonoImage *image, MonoString *s_raw, MonoError *error) /* 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); @@ -296,7 +297,7 @@ method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflect { MONO_REQ_GC_UNSAFE_MODE; - mono_error_init (error); + error_init (error); MonoExceptionClause *clauses; MonoExceptionClause *clause; @@ -373,6 +374,12 @@ mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs) 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 @@ -454,7 +461,7 @@ mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, { MONO_REQ_GC_UNSAFE_MODE; - mono_error_init (error); + error_init (error); memset (rmb, 0, sizeof (ReflectionMethodBuilder)); rmb->ilgen = mb->ilgen; @@ -501,7 +508,7 @@ mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, M const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor"; - mono_error_init (error); + error_init (error); memset (rmb, 0, sizeof (ReflectionMethodBuilder)); @@ -518,7 +525,8 @@ mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, M 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; @@ -639,7 +647,7 @@ mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, cons } -static guint32 +guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec) { MONO_REQ_GC_NEUTRAL_MODE; @@ -720,6 +728,14 @@ mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 origina 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 @@ -730,7 +746,7 @@ is_field_on_inst (MonoClassField *field) #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; @@ -738,7 +754,7 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObjectHandle f, M 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; @@ -751,7 +767,7 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObjectHandle f, M 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; } @@ -848,7 +864,7 @@ mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHel MonoDynamicTable *table; guint32 *values; - mono_error_init (error); + error_init (error); table = &assembly->tables [MONO_TABLE_STANDALONESIG]; idx = table->next_idx ++; @@ -898,7 +914,7 @@ mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMetho 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); @@ -1012,7 +1028,7 @@ mono_image_insert_string (MonoReflectionModuleBuilderHandle ref_module, MonoStri } 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); @@ -1066,7 +1082,7 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj { 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) { @@ -1082,7 +1098,7 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj 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)); @@ -1105,25 +1121,35 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj, 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); @@ -1142,6 +1168,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle 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 @@ -1150,6 +1177,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj, */ 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); @@ -1162,31 +1190,32 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj, 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); + token = mono_image_get_fieldref_token (assembly, field); } /*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); + guint32 array_token = mono_image_get_array_token (assembly, m, error); + if (!is_ok (error)) + goto leave; + token = array_token; } 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)); + guint32 sig_token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error); + if (!is_ok (error)) + goto leave; + token = sig_token; } 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); } @@ -1194,6 +1223,25 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj, #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 @@ -1212,14 +1260,9 @@ mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb) 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; @@ -1255,8 +1298,9 @@ mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb) 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); @@ -1280,7 +1324,7 @@ mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb) 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); } @@ -1303,7 +1347,7 @@ register_module (MonoDomain *domain, MonoReflectionModuleBuilderHandle res, Mono 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); @@ -1351,7 +1395,7 @@ image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *e 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); } @@ -1379,7 +1423,7 @@ MonoType* 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); @@ -1466,7 +1510,7 @@ mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t, Mon 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); @@ -1487,7 +1531,7 @@ MonoType* 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); @@ -1519,7 +1563,7 @@ reflection_instance_handle_mono_type (MonoReflectionGenericClassHandle ref_gclas } 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; } @@ -1539,7 +1583,7 @@ static MonoType* reflection_param_handle_mono_type (MonoReflectionGenericParamHandle ref_gparam, MonoError *error) { HANDLE_FUNCTION_ENTER (); - mono_error_init (error); + error_init (error); MonoType *result = NULL; @@ -1596,7 +1640,7 @@ static MonoType* 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); @@ -1606,7 +1650,7 @@ MonoType* mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error) { HANDLE_FUNCTION_ENTER (); - mono_error_init (error); + error_init (error); MonoType* result = NULL; @@ -1640,10 +1684,18 @@ mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError * 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); @@ -1694,7 +1746,7 @@ parameters_to_signature (MonoImage *image, MonoArrayHandle parameters, MonoError MonoMethodSignature *sig; int count, i; - mono_error_init (error); + error_init (error); count = MONO_HANDLE_IS_NULL (parameters) ? 0 : mono_array_handle_length (parameters); @@ -1718,7 +1770,7 @@ static MonoMethodSignature* 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); @@ -1741,7 +1793,7 @@ static MonoMethodSignature* 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); @@ -1766,7 +1818,7 @@ dynamic_method_to_signature (MonoReflectionDynamicMethodHandle method, MonoError 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)) @@ -1791,7 +1843,7 @@ leave: 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; @@ -1811,7 +1863,7 @@ get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoErro 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; @@ -1923,7 +1975,7 @@ encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuf { MonoTypeEnum simple_type; - mono_error_init (error); + error_init (error); if ((p-buffer) + 10 >= *buflen) { char *newbuf; *buflen *= 2; @@ -2177,7 +2229,7 @@ encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char { int len; - mono_error_init (error); + error_init (error); /* Preallocate a large enough buffer */ if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) { @@ -2216,16 +2268,15 @@ encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char /** * 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) @@ -2238,17 +2289,16 @@ mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObj /** * 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) @@ -2259,7 +2309,7 @@ mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, 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 */ @@ -2336,52 +2386,65 @@ leave: 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); @@ -2409,7 +2472,7 @@ reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoErr 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; @@ -2430,17 +2493,7 @@ reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoErr */ 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")) || @@ -2452,14 +2505,52 @@ reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoErr 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)) @@ -2473,7 +2564,7 @@ reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoErr /*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 (); @@ -2481,23 +2572,25 @@ leave: } /** - * 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); @@ -2538,6 +2631,11 @@ reflection_create_generic_class (MonoReflectionTypeBuilderHandle ref_tb, MonoErr } 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)); } @@ -2548,7 +2646,7 @@ mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly, { MonoMarshalSpec *res; - mono_error_init (error); + error_init (error); res = image_g_new0 (image, MonoMarshalSpec, 1); res->native = (MonoMarshalNative)minfo->type; @@ -2604,7 +2702,7 @@ MonoReflectionMarshalAsAttributeHandle 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)) @@ -2676,7 +2774,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, 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 @@ -2694,7 +2792,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, (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; @@ -2789,6 +2887,8 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, } wrapperm->header = header; + MonoDynamicMethod *dm = (MonoDynamicMethod*)wrapperm; + dm->assembly = klass->image->assembly; } if (rmb->generic_params) { @@ -2976,7 +3076,7 @@ methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilderHandl ReflectionMethodBuilder rmb; MonoMethodSignature *sig; - mono_error_init (error); + error_init (error); mono_loader_lock (); @@ -3004,7 +3104,7 @@ static MonoMethod* 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); @@ -3032,7 +3132,7 @@ fix_partial_generic_class (MonoClass *klass, MonoError *error) MonoClass *gklass = mono_class_get_generic_class (klass)->container_class; int i; - mono_error_init (error); + error_init (error); if (klass->wastypebuilder) return TRUE; @@ -3121,7 +3221,7 @@ ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error) { 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; @@ -3143,7 +3243,7 @@ ensure_runtime_vtable (MonoClass *klass, MonoError *error) 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; @@ -3222,7 +3322,7 @@ ensure_runtime_vtable (MonoClass *klass, MonoError *error) 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; @@ -3252,7 +3352,7 @@ mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides int i, j, onum; MonoReflectionMethod *m; - mono_error_init (error); + error_init (error); *overrides = NULL; *num_overrides = 0; @@ -3324,7 +3424,7 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error) 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; @@ -3361,6 +3461,11 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error) 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); @@ -3386,7 +3491,9 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error) } } - 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 @@ -3399,7 +3506,7 @@ typebuilder_setup_properties (MonoClass *klass, MonoError *error) MonoClassPropertyInfo *info; int i; - mono_error_init (error); + error_init (error); info = mono_class_get_property_info (klass); if (!info) { @@ -3453,7 +3560,7 @@ typebuilder_setup_events (MonoClass *klass, MonoError *error) 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); @@ -3526,12 +3633,51 @@ remove_instantiations_of_and_ensure_contents (gpointer key, 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); @@ -3704,7 +3850,7 @@ reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb, Mono 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", ""); @@ -3779,6 +3925,7 @@ reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb, Mono 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)) { @@ -3786,11 +3933,14 @@ reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb, Mono 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); @@ -3843,7 +3993,7 @@ mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 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) @@ -3863,7 +4013,7 @@ mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 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 */ @@ -3892,7 +4042,7 @@ mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **h 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); @@ -4120,7 +4270,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj, 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; } @@ -4135,13 +4285,13 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle tb, 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; @@ -4150,7 +4300,7 @@ mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error) 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); @@ -4162,14 +4312,14 @@ mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError * 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; @@ -4183,7 +4333,7 @@ ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilderHandle mb, 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; @@ -4211,20 +4361,18 @@ ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb) 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 @@ -4245,16 +4393,30 @@ ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb) } 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); } @@ -4265,10 +4427,12 @@ ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilderHandle module, Mo } 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); }