[runtime] Switch getenv to use heap memory
[mono.git] / mono / metadata / assembly.c
index 33300ffe884fa100278bc414205957f47bf19dbb..a136e34fb3ac95b836e1619a7d118f27f5bdba48 100644 (file)
@@ -76,8 +76,13 @@ static char **assemblies_path = NULL;
 static char **extra_gac_paths = NULL;
 
 #ifndef DISABLE_ASSEMBLY_REMAPPING
+
+static GHashTable* assembly_remapping_table;
 /* The list of system assemblies what will be remapped to the running
- * runtime version. WARNING: this list must be sorted.
+ * runtime version.
+ * This list is stored in @assembly_remapping_table during initialization.
+ * Keep it sorted just to make maintenance easier.
+ *
  * The integer number is an index in the MonoRuntimeInfo structure, whose
  * values can be found in domain.c - supported_runtimes. Look there
  * to understand what remapping will be made.
@@ -133,13 +138,13 @@ static const AssemblyVersionMap framework_assemblies [] = {
        {"System.Drawing", 0},
        {"System.Drawing.Design", 0},
        {"System.EnterpriseServices", 0},
+       {"System.IO.Compression", 2},
        {"System.IdentityModel", 3},
        {"System.IdentityModel.Selectors", 3},
-       {"System.IO.Compression", 2},
        {"System.Management", 0},
        {"System.Messaging", 0},
        {"System.Net", 2},
-       {"System.Net.Http", 3},
+       {"System.Net.Http", 4},
        {"System.Numerics.Vectors", 3},
        {"System.Runtime.InteropServices.RuntimeInformation", 2},
        {"System.Runtime.Remoting", 0},
@@ -289,7 +294,7 @@ mono_set_assemblies_path (const char* path)
        }
        *dest = *splitted;
 
-       if (g_getenv ("MONO_DEBUG") == NULL)
+       if (g_hasenv ("MONO_DEBUG"))
                return;
 
        splitted = assemblies_path;
@@ -310,21 +315,25 @@ char* nacl_mono_path = NULL;
 static void
 check_path_env (void)
 {
-       const char* path;
-       path = g_getenv ("MONO_PATH");
+       if (assemblies_path != NULL)
+               return;
+
+       char* path = g_getenv ("MONO_PATH");
 #ifdef __native_client__
        if (!path)
-               path = nacl_mono_path;
+               path = strdup (nacl_mono_path);
 #endif
-       if (!path || assemblies_path != NULL)
+       if (!path)
                return;
 
        mono_set_assemblies_path(path);
+       g_free (path);
 }
 
 static void
-check_extra_gac_path_env (void) {
-       const char *path;
+check_extra_gac_path_env (void) 
+{
+       char *path;
        char **splitted, **dest;
        
        path = g_getenv ("MONO_GAC_PREFIX");
@@ -332,6 +341,8 @@ check_extra_gac_path_env (void) {
                return;
 
        splitted = g_strsplit (path, G_SEARCHPATH_SEPARATOR_S, 1000);
+       g_free (path);
+
        if (extra_gac_paths)
                g_strfreev (extra_gac_paths);
        extra_gac_paths = dest = splitted;
@@ -342,7 +353,7 @@ check_extra_gac_path_env (void) {
        }
        *dest = *splitted;
        
-       if (g_getenv ("MONO_DEBUG") == NULL)
+       if (!g_hasenv ("MONO_DEBUG"))
                return;
 
        while (*splitted) {
@@ -796,6 +807,15 @@ mono_assemblies_init (void)
 
        mono_os_mutex_init_recursive (&assemblies_mutex);
        mono_os_mutex_init (&assembly_binding_mutex);
+
+#ifndef DISABLE_ASSEMBLY_REMAPPING
+       assembly_remapping_table = g_hash_table_new (g_str_hash, g_str_equal);
+
+       int i;
+       for (i = 0; i < G_N_ELEMENTS (framework_assemblies) - 1; ++i)
+               g_hash_table_insert (assembly_remapping_table, (void*)framework_assemblies [i].assembly_name, (void*)&framework_assemblies [i]);
+
+#endif
 }
 
 static void
@@ -1037,7 +1057,6 @@ static MonoAssemblyName *
 mono_assembly_remap_version (MonoAssemblyName *aname, MonoAssemblyName *dest_aname)
 {
        const MonoRuntimeInfo *current_runtime;
-       int pos, first, last;
 
        if (aname->name == NULL) return aname;
 
@@ -1074,52 +1093,52 @@ mono_assembly_remap_version (MonoAssemblyName *aname, MonoAssemblyName *dest_ana
        }
        
 #ifndef DISABLE_ASSEMBLY_REMAPPING
-       first = 0;
-       last = G_N_ELEMENTS (framework_assemblies) - 1;
-       
-       while (first <= last) {
-               int res;
-               pos = first + (last - first) / 2;
-               res = strcmp (aname->name, framework_assemblies[pos].assembly_name);
-               if (res == 0) {
-                       const AssemblyVersionSet* vset;
-                       int index = framework_assemblies[pos].version_set_index;
-                       g_assert (index < G_N_ELEMENTS (current_runtime->version_sets));
-                       vset = &current_runtime->version_sets [index];
-
-                       if (aname->major == vset->major && aname->minor == vset->minor &&
-                               aname->build == vset->build && aname->revision == vset->revision)
-                               return aname;
-               
-                       if (framework_assemblies[pos].only_lower_versions && compare_versions ((AssemblyVersionSet*)vset, aname) < 0)
-                               return aname;
-
-                       if ((aname->major | aname->minor | aname->build | aname->revision) != 0)
-                               mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY,
-                                       "The request to load the assembly %s v%d.%d.%d.%d was remapped to v%d.%d.%d.%d",
-                                                       aname->name,
-                                                       aname->major, aname->minor, aname->build, aname->revision,
-                                                       vset->major, vset->minor, vset->build, vset->revision
-                                                       );
-                       
-                       memcpy (dest_aname, aname, sizeof(MonoAssemblyName));
-                       dest_aname->major = vset->major;
-                       dest_aname->minor = vset->minor;
-                       dest_aname->build = vset->build;
-                       dest_aname->revision = vset->revision;
-                       if (framework_assemblies[pos].new_assembly_name != NULL) {
-                               dest_aname->name = framework_assemblies[pos].new_assembly_name;
-                               mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY,
-                                                       "The assembly name %s was remapped to %s",
-                                                       aname->name,
-                                                       dest_aname->name);
-                       }
-                       return dest_aname;
-               } else if (res < 0) {
-                       last = pos - 1;
-               } else {
-                       first = pos + 1;
+       const AssemblyVersionMap *vmap = (AssemblyVersionMap *)g_hash_table_lookup (assembly_remapping_table, aname->name);
+       if (vmap) {
+               const AssemblyVersionSet* vset;
+               int index = vmap->version_set_index;
+               g_assert (index < G_N_ELEMENTS (current_runtime->version_sets));
+               vset = &current_runtime->version_sets [index];
+
+               if (aname->major == vset->major && aname->minor == vset->minor &&
+                       aname->build == vset->build && aname->revision == vset->revision) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Found assembly remapping for %s and was for the same version %d.%d.%d.%d",
+                               aname->name,
+                               aname->major, aname->minor, aname->build, aname->revision);
+                       return aname;
+               }
+
+               if (vmap->only_lower_versions && compare_versions ((AssemblyVersionSet*)vset, aname) < 0) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY,
+                               "Found lower-versions-only assembly remaping to load %s %d.%d.%d.%d but mapping has %d.%d.%d.%d",
+                                               aname->name,
+                                               aname->major, aname->minor, aname->build, aname->revision,
+                                               vset->major, vset->minor, vset->build, vset->revision
+                                               );
+                       return aname;
                }
+
+               if ((aname->major | aname->minor | aname->build | aname->revision) != 0)
+                       mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY,
+                               "The request to load the assembly %s v%d.%d.%d.%d was remapped to v%d.%d.%d.%d",
+                                               aname->name,
+                                               aname->major, aname->minor, aname->build, aname->revision,
+                                               vset->major, vset->minor, vset->build, vset->revision
+                                               );
+
+               memcpy (dest_aname, aname, sizeof(MonoAssemblyName));
+               dest_aname->major = vset->major;
+               dest_aname->minor = vset->minor;
+               dest_aname->build = vset->build;
+               dest_aname->revision = vset->revision;
+               if (vmap->new_assembly_name != NULL) {
+                       dest_aname->name = vmap->new_assembly_name;
+                       mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY,
+                                               "The assembly name %s was remapped to %s",
+                                               aname->name,
+                                               dest_aname->name);
+               }
+               return dest_aname;
        }
 #endif
 
@@ -1658,6 +1677,13 @@ mono_assembly_open_from_bundle (const char *filename, MonoImageOpenStatus *statu
 MonoAssembly *
 mono_assembly_open_full (const char *filename, MonoImageOpenStatus *status, gboolean refonly)
 {
+       return mono_assembly_open_a_lot (filename, status, refonly, FALSE);
+}
+
+MonoAssembly *
+mono_assembly_open_a_lot (const char *filename, MonoImageOpenStatus *status, gboolean refonly, gboolean load_from_context)
+{
+
        MonoImage *image;
        MonoAssembly *ass;
        MonoImageOpenStatus def_status;
@@ -1733,7 +1759,7 @@ mono_assembly_open_full (const char *filename, MonoImageOpenStatus *status, gboo
        }
 
        if (!image)
-               image = mono_image_open_full (fname, status, refonly);
+               image = mono_image_open_a_lot (fname, status, refonly, load_from_context);
 
        if (!image){
                if (*status == MONO_IMAGE_OK)
@@ -1889,7 +1915,7 @@ has_reference_assembly_attribute_iterator (MonoImage *image, guint32 typeref_sco
 gboolean
 mono_assembly_has_reference_assembly_attribute (MonoAssembly *assembly, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
 
        /*
         * This might be called during assembly loading, so do everything using the low-level
@@ -3261,7 +3287,7 @@ static MonoAssembly*
 prevent_reference_assembly_from_running (MonoAssembly* candidate, gboolean refonly)
 {
        MonoError refasm_error;
-       mono_error_init (&refasm_error);
+       error_init (&refasm_error);
        if (candidate && !refonly && mono_assembly_has_reference_assembly_attribute (candidate, &refasm_error)) {
                candidate = NULL;
        }