[reflection] Use mono_module_get_object_handle everywhere (#4010)
[mono.git] / mono / metadata / icall.c
index 99ba1d4570dc00753e4facbb08171c02ff10bdea..de0582b7cc1cf8f5f649054f9fc32d3f36bc231e 100644 (file)
@@ -998,6 +998,10 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStac
        // .net seems to check that at least 50% of stack is available
        min_size = thread->stack_size / 2;
 
+       // TODO: It's not always set
+       if (!min_size)
+               return TRUE;
+
        current = (guint8 *)&stack_addr;
        if (current > stack_addr) {
                if ((current - stack_addr) < min_size)
@@ -1591,13 +1595,6 @@ handle_enum:
        return 0;
 }
 
-static gboolean
-mono_type_is_primitive (MonoType *type)
-{
-       return (type->type >= MONO_TYPE_BOOLEAN && type->type <= MONO_TYPE_R8) ||
-                       type-> type == MONO_TYPE_I || type->type == MONO_TYPE_U;
-}
-
 static MonoType*
 mono_type_get_underlying_type_ignore_byref (MonoType *type)
 {
@@ -2094,12 +2091,11 @@ ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *rfield)
        if (image_is_dynamic (field->parent->image)) {
                MonoClass *klass = field->parent;
                int fidx = field - klass->fields;
-               MonoClassExt *ext = mono_class_get_ext (klass);
+               MonoFieldDefaultValue *def_values = mono_class_get_field_def_values (klass);
 
-               g_assert (ext);
-               g_assert (ext->field_def_values);
-               def_type = ext->field_def_values [fidx].def_type;
-               def_value = ext->field_def_values [fidx].data;
+               g_assert (def_values);
+               def_type = def_values [fidx].def_type;
+               def_value = def_values [fidx].data;
 
                if (def_type == MONO_TYPE_END) {
                        mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
@@ -2609,15 +2605,14 @@ ves_icall_reflection_get_token (MonoObject* obj)
        return result;
 }
 
-ICALL_EXPORT MonoReflectionModule*
-ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionType *type)
+ICALL_EXPORT MonoReflectionModuleHandle
+ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionTypeHandle type, MonoError *error)
 {
-       MonoError error;
-       MonoReflectionModule *result = NULL;
-       MonoClass *klass = mono_class_from_mono_type (type->type);
-       result = mono_module_get_object_checked (mono_object_domain (type), klass->image, &error);
-       mono_error_set_pending_exception (&error);
-       return result;
+       mono_error_init (error);
+       MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
+       MonoType *t = MONO_HANDLE_GETVAL (type, type);
+       MonoClass *klass = mono_class_from_mono_type (t);
+       return mono_module_get_object_handle (domain, klass->image, error);
 }
 
 ICALL_EXPORT MonoReflectionAssembly*
@@ -4612,15 +4607,13 @@ leave:
        return res;
 }
 
-ICALL_EXPORT MonoReflectionModule*
-ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly
+ICALL_EXPORT MonoReflectionModuleHandle
+ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssemblyHandle assembly, MonoError *error
 {
-       MonoError error;
-       MonoReflectionModule *result = NULL;
-       result = mono_module_get_object_checked (mono_object_domain (assembly), assembly->assembly->image, &error);
-       if (!mono_error_ok (&error))
-               mono_error_set_pending_exception (&error);
-       return result;
+       mono_error_init (error);
+       MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
+       MonoAssembly *a = MONO_HANDLE_GETVAL (assembly, assembly);
+       return mono_module_get_object_handle (domain, a->image, error);
 }
 
 ICALL_EXPORT MonoArray*
@@ -4665,147 +4658,31 @@ ves_icall_System_Reflection_Assembly_GetAotId (MonoError *error)
        return res;
 }
 
-static MonoObjectHandle
-create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision, MonoError *error)
-{
-       static MonoMethod *create_version = NULL;
-       if (!create_version) {
-               MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
-               create_version = mono_method_desc_search_in_class (desc, mono_class_get_system_version_class ());
-               g_assert (create_version);
-               mono_method_desc_free (desc);
-       }
-       MonoObjectHandle result = NULL_HANDLE;
-
-       mono_error_init (error);
-
-       gpointer args [4];
-       args [0] = &major;
-       args [1] = &minor;
-       args [2] = &build;
-       args [3] = &revision;
-       result = MONO_HANDLE_NEW (MonoObject, mono_object_new_checked (domain, mono_class_get_system_version_class (), error));
-       if (!is_ok (error))
-               goto leave;
-
-       mono_runtime_invoke_checked (create_version, MONO_HANDLE_RAW (result), args, error);
-       if (!is_ok (error))
-               goto leave;
-
-leave:
-       return result;
-}
-
-static MonoReflectionAssemblyNameHandle
+static MonoAssemblyName*
 create_referenced_assembly_name (MonoDomain *domain, MonoImage *image, MonoTableInfo *t, int i, MonoError *error)
 {
        mono_error_init (error);
-
-       static MonoMethod *create_culture = NULL;
-       if (!create_culture) {
-               MonoMethodDesc *desc = mono_method_desc_new (
-                       "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
-               create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
-               g_assert (create_culture);
-               mono_method_desc_free (desc);
-       }
-
-       guint32 cols [MONO_ASSEMBLYREF_SIZE];
-
-       mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
-
-       MonoReflectionAssemblyNameHandle aname =
-               MONO_HANDLE_NEW (MonoReflectionAssemblyName,
-                                mono_object_new_checked (domain, mono_class_get_assembly_name_class (), error));
-       if (!is_ok (error))
-               goto leave;
-
-       MONO_HANDLE_SET (aname, name, mono_string_new_handle (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME]), error));
-       if (!is_ok (error))
-               goto leave;
-
-       gint32 aname_major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION],
-               aname_minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION],
-               aname_build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER],
-               aname_revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
-       MONO_HANDLE_SETVAL (aname, major, gint32, aname_major);
-       MONO_HANDLE_SETVAL (aname, minor, gint32, aname_minor);
-       MONO_HANDLE_SETVAL (aname, build, gint32, aname_build);
-       MONO_HANDLE_SETVAL (aname, revision, gint32, aname_revision);
-       MONO_HANDLE_SETVAL (aname, flags, guint32, cols [MONO_ASSEMBLYREF_FLAGS]);
-       MONO_HANDLE_SETVAL (aname, versioncompat, guint32, 1 /* SameMachine (default) */);
-       MONO_HANDLE_SETVAL (aname, hashalg, guint32, ASSEMBLY_HASH_SHA1 /* SHA1 (default) */);
-
-       MonoObjectHandle version = create_version (domain, aname_major, aname_minor, aname_build, aname_revision, error);
-       if (!is_ok (error))
-               goto leave;
-
-       MONO_HANDLE_SET (aname, version, version);
-
-       gpointer args [2];
-       MonoBoolean assembly_ref = 1;
-       args [0] = mono_string_new_checked (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]), error);
-       args [1] = &assembly_ref;
-       if (!is_ok (error))
-               goto leave;
-
-       MonoObjectHandle cultureInfo = MONO_HANDLE_NEW (MonoObject, mono_runtime_invoke_checked (create_culture, NULL, args, error));
-       if (!is_ok (error))
-               goto leave;
-       MONO_HANDLE_SET (aname, cultureInfo, cultureInfo);
-
-               
-       if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
-               const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
-               guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
-
-               if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
-                       /* public key token isn't copied - the class library will 
-                          automatically generate it from the public key if required */
-                       MonoArrayHandle pkey = mono_array_new_handle (domain, mono_defaults.byte_class, pkey_len, error);
-                       if (!is_ok (error))
-                               goto leave;
-
-                       memcpy (mono_array_addr (MONO_HANDLE_RAW(pkey), guint8, 0), pkey_ptr, pkey_len);
-                       MONO_HANDLE_SET (aname, publicKey, pkey);
-               } else {
-                       MonoArrayHandle keyToken = mono_array_new_handle (domain, mono_defaults.byte_class, pkey_len, error);
-                       if (!is_ok (error))
-                               goto leave;
-
-                       memcpy (mono_array_addr (MONO_HANDLE_RAW(keyToken), guint8, 0), pkey_ptr, pkey_len);
-                       MONO_HANDLE_SET (aname, keyToken, keyToken);
-               }
-       } else {
-               MonoArrayHandle keyToken = mono_array_new_handle (domain, mono_defaults.byte_class, 0, error);
-               if (!is_ok (error))
-                       goto leave;
-
-               MONO_HANDLE_SET (aname, keyToken, keyToken);
-       }
+       MonoAssemblyName *aname = g_new0 (MonoAssemblyName, 1);
+
+       mono_assembly_get_assemblyref (image, i, aname);
+       aname->hash_alg = ASSEMBLY_HASH_SHA1 /* SHA1 (default) */;
+       /* name and culture are pointers into the image tables, but we need
+        * real malloc'd strings (so that we can g_free() them later from
+        * Mono.RuntimeMarshal.FreeAssemblyName) */
+       aname->name = g_strdup (aname->name);
+       aname->culture = g_strdup  (aname->culture);
+       /* Don't need the hash value in managed */
+       aname->hash_value = NULL;
+       aname->hash_len = 0;
+       g_assert (aname->public_key == NULL);
                
-leave:
        /* note: this function doesn't return the codebase on purpose (i.e. it can
           be used under partial trust as path information isn't present). */
        return aname;
 }
 
-static void
-fill_referenced_assemblies (MonoDomain *domain, MonoImage *image, MonoTableInfo *t, int i, MonoArrayHandle referencedAssemblies, MonoError *error)
-{
-       HANDLE_FUNCTION_ENTER();
-       mono_error_init (error);
-
-       MonoReflectionAssemblyNameHandle aname = create_referenced_assembly_name (domain, image, t, i, error);
-       if (!is_ok (error))
-               goto leave;
-       MONO_HANDLE_ARRAY_SETREF (referencedAssemblies, i, aname);
-leave:
-       HANDLE_FUNCTION_RETURN();
-}
-
-ICALL_EXPORT MonoArrayHandle
-ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssemblyHandle assembly, MonoError *error) 
+ICALL_EXPORT GPtrArray*
+ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies (MonoReflectionAssemblyHandle assembly, MonoError *error) 
 {
        mono_error_init (error);
        MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
@@ -4815,13 +4692,13 @@ ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAsse
        MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLYREF];
        int count = t->rows;
 
-       MonoArrayHandle result = mono_array_new_handle (domain, mono_class_get_assembly_name_class (), count, error);
-       return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
+       GPtrArray *result = g_ptr_array_sized_new (count);
 
        for (int i = 0; i < count; i++) {
-               fill_referenced_assemblies (domain, image, t, i, result, error);
+               MonoAssemblyName *aname = create_referenced_assembly_name (domain, image, t, i, error);
                if (!is_ok (error))
                        break;
+               g_ptr_array_add (result, aname);
        }
        return result;
 }
@@ -4844,23 +4721,24 @@ g_concat_dir_and_file (const char *dir, const char *file)
 }
 
 ICALL_EXPORT void *
-ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module
+ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, gint32 *size, MonoReflectionModuleHandleOut ref_module, MonoError *error
 {
-       MonoError error;
-       MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
+       mono_error_init (error);
+       MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
+       MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
+       MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
        guint32 i;
        guint32 cols [MONO_MANIFEST_SIZE];
        guint32 impl, file_idx;
        const char *val;
        MonoImage *module;
 
-       char *n = mono_string_to_utf8_checked (name, &error);
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
+       char *n = mono_string_handle_to_utf8 (name, error);
+       return_val_if_nok (error, NULL);
 
        for (i = 0; i < table->rows; ++i) {
                mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
-               val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
+               val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
                if (strcmp (val, n) == 0)
                        break;
        }
@@ -4877,82 +4755,87 @@ ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflection
                g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
                file_idx = impl >> MONO_IMPLEMENTATION_BITS;
 
-               module = mono_image_load_file_for_image_checked (assembly->assembly->image, file_idx, &error);
-               if (mono_error_set_pending_exception (&error) || !module)
+               module = mono_image_load_file_for_image_checked (assembly->image, file_idx, error);
+               if (!is_ok (error) || !module)
                        return NULL;
        }
        else
-               module = assembly->assembly->image;
+               module = assembly->image;
 
        
-       MonoReflectionModule *rm = mono_module_get_object_checked (mono_domain_get (), module, &error);
-       if (mono_error_set_pending_exception (&error))
+       MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
+       if (!is_ok (error))
                return NULL;
-       mono_gc_wbarrier_generic_store (ref_module, (MonoObject*) rm);
+       MONO_HANDLE_ASSIGN (ref_module, rm);
 
        return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
 }
 
-ICALL_EXPORT gboolean
-ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
+static gboolean
+get_manifest_resource_info_internal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info, MonoError *error)
 {
-       MonoError error;
-       MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
+       HANDLE_FUNCTION_ENTER ();
+       MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
+       MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
+       MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
        int i;
        guint32 cols [MONO_MANIFEST_SIZE];
        guint32 file_cols [MONO_FILE_SIZE];
        const char *val;
        char *n;
 
-       n = mono_string_to_utf8_checked (name, &error);
-       if (mono_error_set_pending_exception (&error))
-               return FALSE;
+       gboolean result = FALSE;
+       
+       n = mono_string_handle_to_utf8 (name, error);
+       if (!is_ok (error))
+               goto leave;
+
        for (i = 0; i < table->rows; ++i) {
                mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
-               val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
+               val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
                if (strcmp (val, n) == 0)
                        break;
        }
        g_free (n);
        if (i == table->rows)
-               return FALSE;
+               goto leave;
 
        if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
-               info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
+               MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST);
        }
        else {
                switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
                case MONO_IMPLEMENTATION_FILE:
                        i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
-                       table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
+                       table = &assembly->image->tables [MONO_TABLE_FILE];
                        mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
-                       val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
-                       MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
+                       val = mono_metadata_string_heap (assembly->image, file_cols [MONO_FILE_NAME]);
+                       MONO_HANDLE_SET (info, filename, mono_string_new_handle (domain, val, error));
                        if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
-                               info->location = 0;
+                               MONO_HANDLE_SETVAL (info, location, guint32, 0);
                        else
-                               info->location = RESOURCE_LOCATION_EMBEDDED;
+                               MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED);
                        break;
 
                case MONO_IMPLEMENTATION_ASSEMBLYREF:
                        i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
-                       mono_assembly_load_reference (assembly->assembly->image, i - 1);
-                       if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
-                               mono_error_set_assembly_load (&error, NULL, "Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
-                               mono_error_set_pending_exception (&error);
-                               return FALSE;
-                       }
-                       MonoReflectionAssembly *assm_obj;
-                       assm_obj = mono_assembly_get_object_checked (mono_domain_get (), assembly->assembly->image->references [i - 1], &error);
-                       if (!assm_obj) {
-                               mono_error_set_pending_exception (&error);
-                               return FALSE;
+                       mono_assembly_load_reference (assembly->image, i - 1);
+                       if (assembly->image->references [i - 1] == REFERENCE_MISSING) {
+                               mono_error_set_assembly_load (error, NULL, "Assembly %d referenced from assembly %s not found ", i - 1, assembly->image->name);
+                               goto leave;
                        }
-                       MONO_OBJECT_SETREF (info, assembly, assm_obj);
+                       MonoReflectionAssemblyHandle assm_obj = mono_assembly_get_object_handle (mono_domain_get (), assembly->image->references [i - 1], error);
+                       if (!is_ok (error))
+                               goto leave;
+                       MONO_HANDLE_SET (info, assembly, assm_obj);
 
                        /* Obtain info recursively */
-                       ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
-                       info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
+                       get_manifest_resource_info_internal (assm_obj, name, info, error);
+                       if (!is_ok (error))
+                               goto leave;
+                       guint32 location = MONO_HANDLE_GETVAL (info, location);
+                       location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
+                       MONO_HANDLE_SETVAL (info, location, guint32, location);
                        break;
 
                case MONO_IMPLEMENTATION_EXP_TYPE:
@@ -4961,7 +4844,16 @@ ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflec
                }
        }
 
-       return TRUE;
+       result = TRUE;
+leave:
+       HANDLE_FUNCTION_RETURN_VAL (result);
+}
+
+ICALL_EXPORT gboolean
+ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info_h, MonoError *error)
+{
+       mono_error_init (error);
+       return get_manifest_resource_info_internal (assembly_h, name, info_h, error);
 }
 
 ICALL_EXPORT MonoObject*
@@ -5019,22 +4911,71 @@ ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *a
        return (MonoObject*)result;
 }
 
-ICALL_EXPORT MonoArray*
-ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
+static gboolean
+add_module_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int *dest_idx, MonoImage* module, MonoError *error)
 {
-       MonoError error;
+       HANDLE_FUNCTION_ENTER ();
+       mono_error_init (error);
+       if (module) {
+               MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
+               if (!is_ok (error))
+                       goto leave;
+               
+               MONO_HANDLE_ARRAY_SETREF (dest, *dest_idx, rm);
+               ++(*dest_idx);
+       }
+
+leave:
+       HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
+}
+
+static gboolean
+add_file_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int dest_idx, MonoImage *image, MonoTableInfo *table, int table_idx,  MonoError *error)
+{
+       HANDLE_FUNCTION_ENTER ();
+       mono_error_init (error);
+
+       guint32 cols [MONO_FILE_SIZE];
+       mono_metadata_decode_row (table, table_idx, cols, MONO_FILE_SIZE);
+       if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
+               MonoReflectionModuleHandle rm = mono_module_file_get_object_handle (domain, image, table_idx, error);
+               if (!is_ok (error))
+                       goto leave;
+               MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
+       } else {
+               MonoImage *m = mono_image_load_file_for_image_checked (image, table_idx + 1, error);
+               if (!is_ok (error))
+                       goto leave;
+               if (!m) {
+                       const char *filename = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
+                       mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
+                       goto leave;
+               }
+               MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, m, error);
+               if (!is_ok (error))
+                       goto leave;
+               MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
+       }
+
+leave:
+       HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
+}
+
+ICALL_EXPORT MonoArrayHandle
+ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
+{
+       mono_error_init (error);
        MonoDomain *domain = mono_domain_get();
-       MonoArray *res;
+       MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
        MonoClass *klass;
        int i, j, file_count = 0;
        MonoImage **modules;
        guint32 module_count, real_module_count;
        MonoTableInfo *table;
-       guint32 cols [MONO_FILE_SIZE];
-       MonoImage *image = assembly->assembly->image;
+       MonoImage *image = assembly->image;
 
        g_assert (image != NULL);
-       g_assert (!assembly_is_dynamic (assembly->assembly));
+       g_assert (!assembly_is_dynamic (assembly));
 
        table = &image->tables [MONO_TABLE_FILE];
        file_count = table->rows;
@@ -5048,51 +4989,29 @@ ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly
                        real_module_count ++;
 
        klass = mono_class_get_module_class ();
-       res = mono_array_new_checked (domain, klass, 1 + real_module_count + file_count, &error);
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
+       MonoArrayHandle res = mono_array_new_handle (domain, klass, 1 + real_module_count + file_count, error);
+       if (!is_ok (error))
+               goto fail;
 
-       MonoReflectionModule *image_obj = mono_module_get_object_checked (domain, image, &error);
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
+       MonoReflectionModuleHandle image_obj = mono_module_get_object_handle (domain, image, error);
+       if (!is_ok (error))
+               goto fail;
+
+       MONO_HANDLE_ARRAY_SETREF (res, 0, image_obj);
 
-       mono_array_setref (res, 0, image_obj);
        j = 1;
        for (i = 0; i < module_count; ++i)
-               if (modules [i]) {
-                       MonoReflectionModule *rm = mono_module_get_object_checked (domain, modules[i], &error);
-                       if (mono_error_set_pending_exception (&error))
-                               return NULL;
-                       mono_array_setref (res, j, rm);
-                       ++j;
-               }
+               if (!add_module_to_modules_array (domain, res, &j, modules[i], error))
+                       goto fail;
 
        for (i = 0; i < file_count; ++i, ++j) {
-               mono_metadata_decode_row (table, i, cols, MONO_FILE_SIZE);
-               if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
-                       MonoReflectionModule *rm = mono_module_file_get_object_checked (domain, image, i, &error);
-                       if (mono_error_set_pending_exception (&error))
-                               return NULL;
-                       mono_array_setref (res, j, rm);
-               }
-               else {
-                       MonoImage *m = mono_image_load_file_for_image_checked (image, i + 1, &error);
-                       if (mono_error_set_pending_exception (&error))
-                               return NULL;
-                       if (!m) {
-                               const char *filename = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
-                               mono_error_set_assembly_load (&error, g_strdup (filename), "%s", "");
-                               mono_error_set_pending_exception (&error);
-                               return NULL;
-                       }
-                       MonoReflectionModule *rm = mono_module_get_object_checked (domain, m, &error);
-                       if (mono_error_set_pending_exception (&error))
-                               return NULL;
-                       mono_array_setref (res, j, rm);
-               }
+               if (!add_file_to_modules_array (domain, res, j, image, table, i, error))
+                       goto fail;
        }
 
        return res;
+fail:
+       return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
 }
 
 ICALL_EXPORT MonoReflectionMethod*
@@ -5621,9 +5540,11 @@ ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssemblyHandle asse
 }
 
 ICALL_EXPORT void
-ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname)
+ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname, gboolean free_struct)
 {
        mono_assembly_name_free (aname);
+       if (free_struct)
+               g_free (aname);
 }
 
 ICALL_EXPORT gboolean