2 * appdomain.c: AppDomain functions
5 * Dietmar Maurer (dietmar@ximian.com)
7 * (C) 2001 Ximian, Inc.
18 #include <mono/metadata/object.h>
19 #include <mono/metadata/appdomain.h>
20 #include <mono/metadata/assembly.h>
21 #include <mono/metadata/exception.h>
22 #include <mono/metadata/cil-coff.h>
26 * @domain: domain returned by mono_init ()
28 * Initialize the core AppDomain: this function will run also some
29 * IL initialization code, so it needs the execution engine to be fully
33 mono_runtime_init (MonoDomain *domain)
35 MonoAppDomainSetup *setup;
39 class = mono_class_from_name (mono_defaults.corlib, "System", "AppDomainSetup");
40 setup = (MonoAppDomainSetup *) mono_object_new (domain, class);
41 ves_icall_System_AppDomainSetup_InitAppDomainSetup (setup);
43 class = mono_class_from_name (mono_defaults.corlib, "System", "AppDomain");
44 ad = (MonoAppDomain *) mono_object_new (domain, class);
47 domain->setup = setup;
53 ves_icall_System_AppDomainSetup_InitAppDomainSetup (MonoAppDomainSetup *setup)
55 // fixme: implement me
59 * mono_domain_transfer_object:
60 * @src: the source domain
61 * @dst: the destination domain
62 * @obj: the object to transfer
64 * This function is used to transfer objects between domains. This is done by
65 * marshalling or serialisation.
68 mono_domain_transfer_object (MonoDomain *src, MonoDomain *dst, MonoObject *obj)
76 g_assert (obj->vtable->domain == src);
78 /* fixme: transfer an object from one domain into another */
80 klass = obj->vtable->klass;
82 if (MONO_CLASS_IS_ARRAY (klass)) {
83 MonoArray *ao = (MonoArray *)obj;
87 esize = mono_array_element_size (klass);
88 if (ao->bounds == NULL) {
89 ecount = mono_array_length (ao);
90 res = (MonoObject *)mono_array_new_full (dst, klass, &ecount, NULL);
93 sizes = alloca (klass->rank * sizeof(guint32) * 2);
95 for (i = 0; i < klass->rank; ++i) {
96 sizes [i] = ao->bounds [i].length;
97 ecount *= ao->bounds [i].length;
98 sizes [i + klass->rank] = ao->bounds [i].lower_bound;
100 res = (MonoObject *)mono_array_new_full (dst, klass, sizes, sizes + klass->rank);
102 if (klass->element_class->valuetype) {
103 memcpy (res, (char *)ao + sizeof(MonoArray), esize * ecount);
105 g_assert (esize == sizeof (gpointer));
106 for (i = 0; i < ecount; i++) {
107 int offset = sizeof (MonoArray) + esize * i;
108 gpointer *src_ea = (gpointer *)((char *)ao + offset);
109 gpointer *dst_ea = (gpointer *)((char *)res + offset);
111 *dst_ea = mono_domain_transfer_object (src, dst, *src_ea);
114 } else if (klass == mono_defaults.string_class) {
115 MonoString *str = (MonoString *)obj;
116 res = (MonoObject *)mono_string_new_utf16 (dst,
117 (const guint16 *)mono_string_chars (str), str->length);
119 // fixme: we need generic marshalling code here */
120 g_assert_not_reached ();
127 ves_icall_System_AppDomain_GetData (MonoAppDomain *ad, MonoString *name)
129 MonoDomain *add = ad->data;
130 MonoDomain *cur = mono_domain_get ();
134 g_assert (ad != NULL);
135 g_assert (name != NULL);
137 str = mono_string_to_utf8 (name);
139 mono_domain_lock (add);
140 if (!strcmp (str, "APPBASE"))
141 o = (MonoObject *)add->setup->application_base;
142 else if (!strcmp (str, "APP_CONFIG_FILE"))
143 o = (MonoObject *)add->setup->configuration_file;
144 else if (!strcmp (str, "DYNAMIC_BASE"))
145 o = (MonoObject *)add->setup->dynamic_base;
146 else if (!strcmp (str, "APP_NAME"))
147 o = (MonoObject *)add->setup->application_name;
148 else if (!strcmp (str, "CACHE_BASE"))
149 o = (MonoObject *)add->setup->cache_path;
150 else if (!strcmp (str, "PRIVATE_BINPATH"))
151 o = (MonoObject *)add->setup->private_bin_path;
152 else if (!strcmp (str, "BINPATH_PROBE_ONLY"))
153 o = (MonoObject *)add->setup->private_bin_path_probe;
154 else if (!strcmp (str, "SHADOW_COPY_DIRS"))
155 o = (MonoObject *)add->setup->shadow_copy_directories;
156 else if (!strcmp (str, "FORCE_CACHE_INSTALL"))
157 o = (MonoObject *)add->setup->shadow_copy_files;
159 o = g_hash_table_lookup (add->env, str);
161 mono_domain_unlock (add);
167 return mono_domain_transfer_object (add, cur, o);
171 ves_icall_System_AppDomain_SetData (MonoAppDomain *ad, MonoString *name, MonoObject *data)
173 MonoDomain *add = ad->data;
174 MonoDomain *cur = mono_domain_get ();
178 g_assert (ad != NULL);
179 g_assert (name != NULL);
181 o = mono_domain_transfer_object (cur, add, data);
183 /* fixme: need a hash func for MonoString */
184 str = mono_string_to_utf8 (name);
185 mono_domain_lock (add);
186 g_hash_table_insert (add->env, str, o);
187 mono_domain_unlock (add);
192 ves_icall_System_AppDomain_getSetup (MonoAppDomain *ad)
194 g_assert (ad != NULL);
195 g_assert (ad->data != NULL);
197 return ad->data->setup;
201 ves_icall_System_AppDomain_getFriendlyName (MonoAppDomain *ad)
203 g_assert (ad != NULL);
204 g_assert (ad->data != NULL);
206 return mono_string_new (ad->data, ad->data->friendly_name);
210 ves_icall_System_AppDomain_getCurDomain ()
212 MonoDomain *add = mono_domain_get ();
217 ves_icall_System_AppDomain_createDomain (MonoString *friendly_name, MonoAppDomainSetup *setup)
219 MonoDomain *domain = mono_domain_get ();
224 adclass = mono_class_from_name (mono_defaults.corlib, "System", "AppDomain");
226 // fixme: pin all those objects
227 ad = (MonoAppDomain *) mono_object_new (domain, adclass);
228 ad->data = data = mono_domain_create ();
231 data->friendly_name = mono_string_to_utf8 (friendly_name);
233 // fixme: what to do next ?
242 } add_assembly_helper_t;
245 add_assembly (gpointer key, gpointer value, gpointer user_data)
247 add_assembly_helper_t *ah = (add_assembly_helper_t *) user_data;
249 mono_array_set (ah->res, gpointer, ah->idx++, mono_assembly_get_object (ah->domain, value));
253 ves_icall_System_AppDomain_GetAssemblies (MonoAppDomain *ad)
255 MonoDomain *domain = ad->data;
256 static MonoClass *System_Reflection_Assembly;
258 add_assembly_helper_t ah;
260 if (!System_Reflection_Assembly)
261 System_Reflection_Assembly = mono_class_from_name (
262 mono_defaults.corlib, "System.Reflection", "Assembly");
264 res = mono_array_new (domain, System_Reflection_Assembly, g_hash_table_size (domain->assemblies));
269 mono_domain_lock (domain);
270 g_hash_table_foreach (domain->assemblies, add_assembly, &ah);
271 mono_domain_unlock (domain);
276 MonoReflectionAssembly *
277 ves_icall_System_Reflection_Assembly_LoadFrom (MonoString *fname)
279 MonoDomain *domain = mono_domain_get ();
280 char *name, *filename;
281 MonoImageOpenStatus status = MONO_IMAGE_OK;
284 name = filename = mono_string_to_utf8 (fname);
286 /* FIXME: move uri handling to mono_assembly_open */
287 if (strncmp (filename, "file://", 7) == 0)
290 ass = mono_assembly_open (filename, &status);
295 mono_raise_exception ((MonoException *)mono_exception_from_name (mono_defaults.corlib, "System.IO", "FileNotFoundException"));
297 return mono_assembly_get_object (domain, ass);
301 MonoReflectionAssembly *
302 ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad, MonoReflectionAssemblyName *assRef, MonoObject *evidence)
304 MonoDomain *domain = ad->data;
306 MonoImageOpenStatus status = MONO_IMAGE_OK;
308 MonoAssemblyName aname;
310 memset (&aname, 0, sizeof (aname));
312 /* FIXME : examine evidence? */
314 g_assert (assRef != NULL);
315 g_assert (assRef->name != NULL);
317 /* FIXME : examine version, culture info */
319 name = aname.name = mono_string_to_utf8 (assRef->name);
321 ass = mono_assembly_load (&aname, NULL, &status);
326 mono_raise_exception ((MonoException *)mono_exception_from_name (mono_defaults.corlib, "System.IO", "FileNotFoundException"));
328 return mono_assembly_get_object (domain, ass);
332 ves_icall_System_AppDomain_Unload (MonoAppDomain *ad)
334 mono_domain_unload (ad->data, FALSE);
338 ves_icall_System_AppDomain_ExecuteAssembly (MonoAppDomain *ad, MonoString *file,
339 MonoObject *evidence, MonoArray *args)
341 MonoDomain *cdom = mono_domain_get ();
342 MonoAssembly *assembly;
344 MonoCLIImageInfo *iinfo;
350 mono_domain_set (ad->data);
352 filename = mono_string_to_utf8 (file);
353 assembly = mono_assembly_open (filename, NULL);
357 mono_raise_exception ((MonoException *)mono_exception_from_name (
358 mono_defaults.corlib, "System.IO", "FileNotFoundException"));
361 image = assembly->image;
362 iinfo = image->image_info;
363 method = mono_get_method (image, iinfo->cli_cli_header.ch_entry_point, NULL);
366 g_error ("No entry point method found in %s", image->name);
368 margs = mono_domain_transfer_object (cdom, ad->data, (MonoObject *)args);
369 res = mono_runtime_exec_main (method, (MonoArray *)margs, NULL);
371 mono_domain_set (cdom);