#define CSIZE(x) (sizeof (x) / 4)
+/*
+ * keeps track of loaded assemblies
+ */
+static GHashTable *assemblies;
+
/**
* g_concat_dir_and_file:
* @dir: directory name
}
static char *
-default_assembly_name_resolver (const char *name)
+default_assembly_name_resolver (const char *base_dir, const char *name)
{
char *file, *path;
- if (strcmp (name, "mscorlib") == 0)
+ if ((strcmp (name, "mscorlib") == 0) ||
+ (strcmp (name, "mscorlib.dll") == 0) ||
+ (strcmp (name, "corlib.dll") == 0) ||
+ (strcmp (name, "corlib") == 0))
return g_concat_dir_and_file (MONO_ASSEMBLIES, CORLIB_NAME);
+ path = g_concat_dir_and_file (base_dir, name);
+ if (g_file_test (name, G_FILE_TEST_EXISTS))
+ return path;
+
+ file = path;
+ path = g_strconcat (file, ".dll", NULL);
+ g_free (file);
+ if (g_file_test (path, G_FILE_TEST_EXISTS))
+ return path;
+ g_free (path);
+
+ path = g_concat_dir_and_file (MONO_ASSEMBLIES, name);
+ if (g_file_test (path, G_FILE_TEST_EXISTS))
+ return path;
+ g_free (path);
+
file = g_strconcat (name, ".dll", NULL);
path = g_concat_dir_and_file (MONO_ASSEMBLIES, file);
g_free (file);
MonoImage *image;
MonoTableInfo *t;
int i;
- const char *basename = strrchr (filename, '/');
+ char *fullname, *base_dir;
+ const char *base_name = strrchr (filename, G_DIR_SEPARATOR);
static MonoAssembly *corlib;
g_return_val_if_fail (filename != NULL, NULL);
- if (basename == NULL)
- basename = filename;
+ if (assemblies == NULL)
+ assemblies = g_hash_table_new (g_str_hash, g_str_equal);
+
+ if ((ass = g_hash_table_lookup (assemblies, filename)) != NULL){
+ ass->ref_count++;
+ return ass;
+ }
+
+ if (base_name == NULL)
+ base_name = filename;
else
- basename++;
+ base_name++;
- /*
- * Temporary hack until we have a complete corlib.dll
- */
- if (strcmp (basename, CORLIB_NAME) == 0) {
- char *fullname;
-
- if (corlib != NULL)
- return corlib;
- fullname = g_concat_dir_and_file (MONO_ASSEMBLIES, CORLIB_NAME);
- image = mono_image_open (fullname, status);
- g_free (fullname);
- } else
- image = mono_image_open (filename, status);
+ if (resolver == NULL)
+ resolver = default_assembly_name_resolver;
+
+ base_dir = g_path_get_dirname (fullname);
+ fullname = resolver (base_dir, filename);
+ image = mono_image_open (fullname, status);
+
if (!image){
if (status)
*status = MONO_IMAGE_ERROR_ERRNO;
+ g_free (fullname);
+ g_free (base_dir);
return NULL;
}
- if (resolver == NULL)
- resolver = default_assembly_name_resolver;
-
t = &image->tables [MONO_TABLE_ASSEMBLYREF];
image->references = g_new0 (MonoAssembly *, t->rows + 1);
+ /*
+ * Create assembly struct, and enter it into the assembly cache
+ */
ass = g_new (MonoAssembly, 1);
+ ass->name = fullname;
ass->image = image;
+
+ g_hash_table_insert (assemblies, image->name, ass);
+ g_hash_table_insert (assemblies, ass->name, ass);
/*
* Load any assemblies this image references
* ie, references to mscorlib from corlib.dll are ignored
* and we do not load corlib twice.
*/
- if (strcmp (basename, CORLIB_NAME) == 0){
+ if (strcmp (base_name, CORLIB_NAME) == 0){
if (corlib == NULL)
corlib = ass;
continue;
}
- assembly_ref = (*resolver) (name);
+ assembly_ref = (*resolver) (base_dir, name);
image->references [i] = mono_assembly_open (assembly_ref, resolver, status);
if (status)
*status = MONO_IMAGE_MISSING_ASSEMBLYREF;
g_free (ass);
+ g_free (base_dir);
return NULL;
}
g_free (assembly_ref);
}
image->references [i] = NULL;
+ g_free (base_dir);
return ass;
}
g_return_if_fail (assembly != NULL);
+ if (--assembly->ref_count != 0)
+ return;
+
image = assembly->image;
for (i = 0; image->references [i] != NULL; i++)
mono_image_close (image->references [i]->image);
g_free (image->references);
mono_image_close (assembly->image);
+
+ g_hash_table_remove (assemblies, assembly->name);
+
+ g_free (assembly->name);
g_free (assembly);
}
+/*
+ * Temporary hack until we get AppDomains
+ */
+GHashTable *
+mono_get_assemblies ()
+{
+ return assemblies;
+}