X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fsre.c;h=48df45db99732e672656cef36644cfca5cd8081f;hb=391dca598831ef87d928354824d5861909cbfb6d;hp=9e4f12c75f6ddb7c229d751b0fa4c1ac0c8b8fb7;hpb=a8dfce54660780a583baf1eca4968eb1712102ce;p=mono.git diff --git a/mono/metadata/sre.c b/mono/metadata/sre.c index 9e4f12c75f6..48df45db997 100644 --- a/mono/metadata/sre.c +++ b/mono/metadata/sre.c @@ -43,7 +43,6 @@ 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); @@ -375,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 @@ -520,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; @@ -641,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; @@ -722,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 @@ -732,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; @@ -740,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; @@ -753,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; } @@ -1014,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); @@ -1084,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)); @@ -1107,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; 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); @@ -1144,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 @@ -1152,9 +1177,24 @@ 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); + 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) { @@ -1164,31 +1204,44 @@ 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); + 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); } @@ -1196,6 +1249,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 @@ -1214,14 +1286,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; @@ -1257,8 +1324,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); @@ -1282,7 +1350,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); } @@ -1642,10 +1710,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); @@ -2422,7 +2498,7 @@ reflection_setup_internal_class_internal (MonoReflectionTypeBuilderHandle ref_tb 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; @@ -2443,7 +2519,7 @@ reflection_setup_internal_class_internal (MonoReflectionTypeBuilderHandle ref_tb */ 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)); + 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")) || @@ -2514,7 +2590,7 @@ reflection_setup_internal_class_internal (MonoReflectionTypeBuilderHandle ref_tb /*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 (); @@ -2581,6 +2657,11 @@ reflection_init_generic_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError } 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)); } @@ -2737,7 +2818,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; @@ -2832,6 +2913,8 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, } wrapperm->header = header; + MonoDynamicMethod *dm = (MonoDynamicMethod*)wrapperm; + dm->assembly = klass->image->assembly; } if (rmb->generic_params) { @@ -3404,6 +3487,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); @@ -3429,7 +3517,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 @@ -3861,6 +3951,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)) { @@ -3868,11 +3959,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); @@ -4244,7 +4338,7 @@ 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); } @@ -4294,19 +4388,17 @@ void ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, guint32 token, MonoError *error) { error_init (error); - mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb, dynamic_image), token, obj); + /* 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 @@ -4327,10 +4419,24 @@ 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 @@ -4347,10 +4453,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); }