Browse Source

2002-11-03 Gonzalo Paniagua Javier <[email protected]>

	* 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
Gonzalo Paniagua Javier 23 years ago
parent
commit
90c3d84c1e
3 changed files with 84 additions and 4 deletions
  1. 7 0
      mono/metadata/ChangeLog
  2. 75 2
      mono/metadata/appdomain.c
  3. 2 2
      mono/metadata/icall.c

+ 7 - 0
mono/metadata/ChangeLog

@@ -1,3 +1,10 @@
+2002-11-03  Gonzalo Paniagua Javier <[email protected]>
+
+	* 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  <[email protected]>
 
 	* icall.c: 

+ 75 - 2
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);

+ 2 - 2
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,