From 90c3d84c1e78c8aef1c8233e51582fc770e5c435 Mon Sep 17 00:00:00 2001 From: Gonzalo Paniagua Javier Date: Sun, 3 Nov 2002 02:02:11 +0000 Subject: [PATCH] 2002-11-03 Gonzalo Paniagua Javier * appdomain.c: invoke AssemblyLoad and AsemblyResolve events in the current domain when loaded an assembly and failed to load it. * icall.c: changed ...Assembly_GetType to Assembly_InternalGetType. svn path=/trunk/mono/; revision=8787 --- mono/metadata/ChangeLog | 7 ++++ mono/metadata/appdomain.c | 77 ++++++++++++++++++++++++++++++++++++++- mono/metadata/icall.c | 4 +- 3 files changed, 84 insertions(+), 4 deletions(-) diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog index 12ca5a86cc9..c979abb6a09 100644 --- a/mono/metadata/ChangeLog +++ b/mono/metadata/ChangeLog @@ -1,3 +1,10 @@ +2002-11-03 Gonzalo Paniagua Javier + + * appdomain.c: invoke AssemblyLoad and AsemblyResolve events in the + current domain when loaded an assembly and failed to load it. + + * icall.c: changed ...Assembly_GetType to Assembly_InternalGetType. + 2002-10-31 Dick Porter * icall.c: diff --git a/mono/metadata/appdomain.c b/mono/metadata/appdomain.c index 098e0e6ba18..20d9f29679a 100644 --- a/mono/metadata/appdomain.c +++ b/mono/metadata/appdomain.c @@ -26,6 +26,8 @@ CRITICAL_SECTION mono_delegate_section; static MonoObject * mono_domain_transfer_object (MonoDomain *src, MonoDomain *dst, MonoObject *obj); +static void +mono_domain_fire_assembly_load (MonoAssembly *assembly, gpointer user_data); /* * mono_runtime_init: @@ -42,6 +44,8 @@ mono_runtime_init (MonoDomain *domain, MonoThreadStartCB start_cb) MonoAppDomain *ad; MonoClass *class; + mono_install_assembly_load_hook (mono_domain_fire_assembly_load, NULL); + class = mono_class_from_name (mono_defaults.corlib, "System", "AppDomainSetup"); setup = (MonoAppDomainSetup *) mono_object_new (domain, class); ves_icall_System_AppDomainSetup_InitAppDomainSetup (setup); @@ -534,6 +538,71 @@ ves_icall_System_AppDomain_GetAssemblies (MonoAppDomain *ad) return res; } +/* + * Used to find methods in AppDomain class. + * It only works if there are no multiple signatures for any given method name + */ +static MonoMethod * +look_for_method_by_name (MonoClass *klass, const gchar *name) +{ + gint i; + MonoMethod *method; + + for (i = 0; i < klass->method.count; i++) { + method = klass->methods [i]; + if (!strcmp (method->name, name)) + return method; + } + + return NULL; +} + +static MonoReflectionAssembly * +try_assembly_resolve (MonoDomain *domain, MonoString *fname) +{ + MonoClass *klass; + MonoMethod *method; + void *params [1]; + + g_assert (domain != NULL && fname != NULL); + + klass = domain->domain->object.vtable->klass; + g_assert (klass); + + method = look_for_method_by_name (klass, "DoAssemblyResolve"); + if (method == NULL) { + g_warning ("Method AppDomain.DoAssemblyResolve not found.\n"); + return NULL; + } + + *params = fname; + return (MonoReflectionAssembly *) mono_runtime_invoke (method, domain->domain, params, NULL); +} + +static void +mono_domain_fire_assembly_load (MonoAssembly *assembly, gpointer user_data) +{ + MonoDomain *domain = mono_domain_get (); + MonoReflectionAssembly *ref_assembly; + MonoClass *klass; + MonoMethod *method; + void *params [1]; + + klass = domain->domain->object.vtable->klass; + + method = look_for_method_by_name (klass, "DoAssemblyLoad"); + if (method == NULL) { + g_warning ("Method AppDomain.DoAssemblyLoad not found.\n"); + return; + } + + ref_assembly = mono_assembly_get_object (domain, assembly); + g_assert (ref_assembly); + + *params = ref_assembly; + mono_runtime_invoke (method, domain->domain, params, NULL); +} + MonoReflectionAssembly * ves_icall_System_Reflection_Assembly_LoadFrom (MonoString *fname) { @@ -569,6 +638,7 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad, MonoReflectionAssem MonoImageOpenStatus status = MONO_IMAGE_OK; MonoAssembly *ass; MonoAssemblyName aname; + MonoReflectionAssembly *refass = NULL; memset (&aname, 0, sizeof (aname)); @@ -585,12 +655,15 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad, MonoReflectionAssem g_free (name); - if (!ass) { + if (!ass && (refass = try_assembly_resolve (domain, assRef->name)) == NULL){ /* FIXME: it doesn't make much sense since we really don't have a filename ... */ MonoException *exc = mono_get_exception_file_not_found (assRef->name); mono_raise_exception (exc); } + if (refass != NULL) + return refass; + return mono_assembly_get_object (domain, ass); } @@ -632,7 +705,7 @@ ves_icall_System_AppDomain_ExecuteAssembly (MonoAppDomain *ad, MonoString *file, margs = mono_domain_transfer_object (cdom, ad->data, (MonoObject *)args); if (!margs) - margs = mono_array_new (ad->data, mono_defaults.string_class, 0); + margs = (MonoObject *) mono_array_new (ad->data, mono_defaults.string_class, 0); res = mono_runtime_exec_main (method, (MonoArray *)margs, NULL); mono_domain_set (cdom); diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index dbc90780e20..f8bc26c1f09 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -1794,7 +1794,7 @@ ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags) } static MonoReflectionType* -ves_icall_System_Reflection_Assembly_GetType (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase) +ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase) { gchar *str; MonoType *type; @@ -2929,7 +2929,7 @@ static gconstpointer icall_map [] = { "System.Reflection.Assembly::LoadFrom", ves_icall_System_Reflection_Assembly_LoadFrom, - "System.Reflection.Assembly::GetType", ves_icall_System_Reflection_Assembly_GetType, + "System.Reflection.Assembly::InternalGetType", ves_icall_System_Reflection_Assembly_InternalGetType, "System.Reflection.Assembly::GetTypes", ves_icall_System_Reflection_Assembly_GetTypes, "System.Reflection.Assembly::FillName", ves_icall_System_Reflection_Assembly_FillName, "System.Reflection.Assembly::get_code_base", ves_icall_System_Reflection_Assembly_get_code_base, -- 2.25.1