[reflection] Use handles for System.Reflection.Assembly.GetTypes
authorAleksey Kliger <aleksey@xamarin.com>
Thu, 17 Nov 2016 22:28:42 +0000 (17:28 -0500)
committerAleksey Kliger <aleksey@xamarin.com>
Fri, 18 Nov 2016 15:21:26 +0000 (10:21 -0500)
Also change mono_get_exception_reflection_type_load_checked() to use handles.

mono/metadata/exception-internals.h
mono/metadata/exception.c
mono/metadata/icall-def.h
mono/metadata/icall.c

index 4a9ad505798ee867cfab121d1afcf84069b6d44a..a0f4c783fa14e47ff5a49488fb543101598877f0 100644 (file)
@@ -4,13 +4,14 @@
 #include <glib.h>
 
 #include <mono/metadata/object.h>
+#include <mono/metadata/handle.h>
 #include <mono/utils/mono-error.h>
 
 MonoException *
 mono_get_exception_type_initialization_checked (const gchar *type_name, MonoException *inner, MonoError *error);
 
-MonoException *
-mono_get_exception_reflection_type_load_checked (MonoArray *types, MonoArray *exceptions, MonoError *error);
+MonoExceptionHandle
+mono_get_exception_reflection_type_load_checked (MonoArrayHandle types, MonoArrayHandle exceptions, MonoError *error);
 
 MonoException *
 mono_get_exception_runtime_wrapped_checked (MonoObject *wrapped_exception, MonoError *error);
index 79454c3f38b5810ea8c2ce529c0d9e576e277b20..d8bdf35dfa53913f53b3eca1724b804ae856bfc5 100644 (file)
@@ -842,27 +842,33 @@ mono_get_exception_method_access_msg (const char *msg)
  * Returns: a new instance of the `System.Reflection.ReflectionTypeLoadException`
  */
 MonoException *
-mono_get_exception_reflection_type_load (MonoArray *types, MonoArray *exceptions)
+mono_get_exception_reflection_type_load (MonoArray *types_raw, MonoArray *exceptions_raw)
 {
+       HANDLE_FUNCTION_ENTER ();
        MonoError error;
-       MonoException *ret = mono_get_exception_reflection_type_load_checked (types, exceptions, &error);
+       MONO_HANDLE_DCL (MonoArray, types);
+       MONO_HANDLE_DCL (MonoArray, exceptions);
+       MonoExceptionHandle ret = mono_get_exception_reflection_type_load_checked (types, exceptions, &error);
        if (is_ok (&error)) {
                mono_error_cleanup (&error);
-               return NULL;
+               ret = MONO_HANDLE_CAST (MonoException, NULL_HANDLE);
+               goto leave;
        }
 
-       return ret;
+leave:
+       HANDLE_FUNCTION_RETURN_OBJ (ret);
+
 }
 
-MonoException *
-mono_get_exception_reflection_type_load_checked (MonoArray *types, MonoArray *exceptions, MonoError *error)
+MonoExceptionHandle
+mono_get_exception_reflection_type_load_checked (MonoArrayHandle types, MonoArrayHandle exceptions, MonoError *error)
 {
        MonoClass *klass;
-       gpointer args [2];
-       MonoObject *exc;
        MonoMethod *method;
        gpointer iter;
 
+       mono_error_init (error);
+
        klass = mono_class_load_from_name (mono_get_corlib (), "System.Reflection", "ReflectionTypeLoadException");
 
        mono_class_init (klass);
@@ -880,16 +886,17 @@ mono_get_exception_reflection_type_load_checked (MonoArray *types, MonoArray *ex
        }
        g_assert (method);
 
-       args [0] = types;
-       args [1] = exceptions;
-
-       exc = mono_object_new_checked (mono_domain_get (), klass, error);
+       MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, mono_object_new_checked (mono_domain_get (), klass, error));
        mono_error_assert_ok (error);
 
-       mono_runtime_invoke_checked (method, exc, args, error);
-       return_val_if_nok (error, NULL);
+       gpointer args [2];
+       args [0] = MONO_HANDLE_RAW (types);
+       args [1] = MONO_HANDLE_RAW (exceptions);
 
-       return (MonoException *) exc;
+       mono_runtime_invoke_checked (method, MONO_HANDLE_RAW (exc), args, error);
+       return_val_if_nok (error, MONO_HANDLE_CAST (MonoException, NULL_HANDLE));
+
+       return exc;
 }
 
 MonoException *
index c9f043dc88700d7c583386e729924943e57db13d..14c25d7ff570e1f520b7f338574a1117d0a32d52 100644 (file)
@@ -510,7 +510,7 @@ ICALL(ASSEM_9, "GetManifestResourceNames", ves_icall_System_Reflection_Assembly_
 ICALL(ASSEM_10, "GetModulesInternal", ves_icall_System_Reflection_Assembly_GetModulesInternal)
 //ICALL(ASSEM_11, "GetNamespaces", ves_icall_System_Reflection_Assembly_GetNamespaces)
 ICALL(ASSEM_12, "GetReferencedAssemblies", ves_icall_System_Reflection_Assembly_GetReferencedAssemblies)
-ICALL(ASSEM_13, "GetTypes", ves_icall_System_Reflection_Assembly_GetTypes)
+HANDLES(ICALL(ASSEM_13, "GetTypes", ves_icall_System_Reflection_Assembly_GetTypes))
 ICALL(ASSEM_14, "InternalGetAssemblyName", ves_icall_System_Reflection_Assembly_InternalGetAssemblyName)
 ICALL(ASSEM_15, "InternalGetType", ves_icall_System_Reflection_Assembly_InternalGetType)
 HANDLES(ICALL(ASSEM_16, "InternalImageRuntimeVersion", ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion))
index 6b57e5e694c72042c7384297226f0dec0bf2e7de..6b62ca22c67873e9f074e8399bb3d1498ab2d92d 100644 (file)
@@ -5553,76 +5553,80 @@ mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArrayHandleOut
        return res;
 }
 
-static MonoArray*
-mono_module_get_types_legacy (MonoDomain *domain, MonoImage *image, MonoArray **exceptions_raw, MonoBoolean exportedOnly, MonoError *error)
+static void
+append_module_types (MonoDomain *domain, MonoArrayHandleOut res, MonoArrayHandleOut exceptions, MonoImage *image, MonoBoolean exportedOnly, MonoError *error)
 {
-       /* FIXME: don't use this function, update callers to use mono_module_get_types */
        HANDLE_FUNCTION_ENTER ();
        mono_error_init (error);
-       MonoArrayHandle exceptions = MONO_HANDLE_NEW (MonoArray, NULL);
-       MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, exportedOnly, error);
-       mono_gc_wbarrier_generic_store (exceptions_raw, MONO_HANDLE_RAW (MONO_HANDLE_CAST (MonoObject, exceptions)));
-       HANDLE_FUNCTION_RETURN_OBJ (res);
-}
+       MonoArrayHandle ex2 = MONO_HANDLE_NEW (MonoArray, NULL);
+       MonoArrayHandle res2 = mono_module_get_types (domain, image, ex2, exportedOnly, error);
+       if (!is_ok (error))
+               goto leave;
 
-ICALL_EXPORT MonoArray*
-ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
-{
-       MonoError error;
-       MonoArray *res = NULL;
-       MonoArray *exceptions = NULL;
-       MonoImage *image = NULL;
-       MonoTableInfo *table = NULL;
-       MonoDomain *domain;
-       GList *list = NULL;
-       int i, len, ex_count;
+       /* Append the new types to the end of the array */
+       if (mono_array_handle_length (res2) > 0) {
+               guint32 len1, len2;
 
-       domain = mono_object_domain (assembly);
+               len1 = mono_array_handle_length (res);
+               len2 = mono_array_handle_length (res2);
 
-       g_assert (!assembly_is_dynamic (assembly->assembly));
-       image = assembly->assembly->image;
-       table = &image->tables [MONO_TABLE_FILE];
-       res = mono_module_get_types_legacy (domain, image, &exceptions, exportedOnly, &error); /* FIXME no _legacy */
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
+               MonoArrayHandle res3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
+               if (!is_ok (error))
+                       goto leave;
 
-       /* Append data from all modules in the assembly */
-       for (i = 0; i < table->rows; ++i) {
-               if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
-                       MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, &error);
-                       if (mono_error_set_pending_exception (&error))
-                               return NULL;
-                       if (loaded_image) {
-                               MonoArray *ex2;
-                               MonoArray *res2;
+               mono_array_handle_memcpy_refs (res3, 0, res, 0, len1);
+               mono_array_handle_memcpy_refs (res3, len1, res2, 0, len2);
+               MONO_HANDLE_ASSIGN (res, res3);
 
-                               res2 = mono_module_get_types_legacy (domain, loaded_image, &ex2, exportedOnly, &error); /* FIXME no _legacy */
-                               if (mono_error_set_pending_exception (&error))
-                                       return NULL;
+               MonoArrayHandle ex3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
+               if (!is_ok (error))
+                       goto leave;
 
+               mono_array_handle_memcpy_refs (ex3, 0, exceptions, 0, len1);
+               mono_array_handle_memcpy_refs (ex3, len1, ex2, 0, len2);
+               MONO_HANDLE_ASSIGN (exceptions, ex3);
+       }
+leave:
+       HANDLE_FUNCTION_RETURN ();
+}
 
-                               /* Append the new types to the end of the array */
-                               if (mono_array_length (res2) > 0) {
-                                       guint32 len1, len2;
-                                       MonoArray *res3, *ex3;
+static void
+set_class_failure_in_array (MonoArrayHandle exl, int i, MonoClass *klass)
+{
+       HANDLE_FUNCTION_ENTER ();
+       MonoError unboxed_error;
+       mono_error_init (&unboxed_error);
+       mono_error_set_for_class_failure (&unboxed_error, klass);
 
-                                       len1 = mono_array_length (res);
-                                       len2 = mono_array_length (res2);
+       MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, mono_error_convert_to_exception (&unboxed_error));
+       MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
+       HANDLE_FUNCTION_RETURN ();
+}
 
-                                       res3 = mono_array_new_checked (domain, mono_defaults.runtimetype_class, len1 + len2, &error);
-                                       if (mono_error_set_pending_exception (&error))
-                                               return NULL;
-                                       mono_array_memcpy_refs (res3, 0, res, 0, len1);
-                                       mono_array_memcpy_refs (res3, len1, res2, 0, len2);
-                                       res = res3;
+ICALL_EXPORT MonoArrayHandle
+ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssemblyHandle assembly_handle, MonoBoolean exportedOnly, MonoError *error)
+{
+       MonoArrayHandle exceptions = MONO_HANDLE_NEW(MonoArray, NULL);
+       int i;
 
-                                       ex3 = mono_array_new_checked (domain, mono_defaults.runtimetype_class, len1 + len2, &error);
-                                       if (mono_error_set_pending_exception (&error))
-                                               return NULL;
-                                       mono_array_memcpy_refs (ex3, 0, exceptions, 0, len1);
-                                       mono_array_memcpy_refs (ex3, len1, ex2, 0, len2);
-                                       exceptions = ex3;
-                               }
+       MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_handle);
+       MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
+
+       g_assert (!assembly_is_dynamic (assembly));
+       MonoImage *image = assembly->image;
+       MonoTableInfo *table = &image->tables [MONO_TABLE_FILE];
+       MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, exportedOnly, error);
+       return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
+
+       /* Append data from all modules in the assembly */
+       for (i = 0; i < table->rows; ++i) {
+               if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
+                       MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, error);
+                       return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
+
+                       if (loaded_image) {
+                               append_module_types (domain, res, exceptions, loaded_image, exportedOnly, error);
+                               return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
                        }
                }
        }
@@ -5632,20 +5636,21 @@ ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly,
         * contain all exceptions for NULL items.
         */
 
-       len = mono_array_length (res);
+       int len = mono_array_handle_length (res);
 
-       ex_count = 0;
+       int ex_count = 0;
+       GList *list = NULL;
+       MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
        for (i = 0; i < len; i++) {
-               MonoReflectionType *t = (MonoReflectionType *)mono_array_get (res, gpointer, i);
-               MonoClass *klass;
+               MONO_HANDLE_ARRAY_GETREF (t, res, i);
 
-               if (t) {
-                       klass = mono_type_get_class (t->type);
+               if (!MONO_HANDLE_IS_NULL (t)) {
+                       MonoClass *klass = mono_type_get_class (MONO_HANDLE_GETVAL (t, type));
                        if ((klass != NULL) && mono_class_has_failure (klass)) {
                                /* keep the class in the list */
                                list = g_list_append (list, klass);
                                /* and replace Type with NULL */
-                               mono_array_setref (res, i, NULL);
+                               MONO_HANDLE_ARRAY_SETRAW (res, i, NULL);
                        }
                } else {
                        ex_count ++;
@@ -5654,39 +5659,36 @@ ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly,
 
        if (list || ex_count) {
                GList *tmp = NULL;
-               MonoException *exc = NULL;
-               MonoArray *exl = NULL;
                int j, length = g_list_length (list) + ex_count;
 
-               exl = mono_array_new_checked (domain, mono_defaults.exception_class, length, &error);
-               if (mono_error_set_pending_exception (&error)) {
+               MonoArrayHandle exl = mono_array_new_handle (domain, mono_defaults.exception_class, length, error);
+               if (!is_ok (error)) {
                        g_list_free (list);
-                       return NULL;
+                       return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
                }
                /* Types for which mono_class_get_checked () succeeded */
+               MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, NULL);
                for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
-                       MonoException *exc = mono_class_get_exception_for_failure ((MonoClass *)tmp->data);
-                       mono_array_setref (exl, i, exc);
+                       set_class_failure_in_array (exl, i, (MonoClass*)tmp->data);
                }
                /* Types for which it don't */
-               for (j = 0; j < mono_array_length (exceptions); ++j) {
-                       MonoException *exc = mono_array_get (exceptions, MonoException*, j);
-                       if (exc) {
+               for (j = 0; j < mono_array_handle_length (exceptions); ++j) {
+                       MONO_HANDLE_ARRAY_GETREF (exc, exceptions, j);
+                       if (!MONO_HANDLE_IS_NULL (exc)) {
                                g_assert (i < length);
-                               mono_array_setref (exl, i, exc);
+                               MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
                                i ++;
                        }
                }
                g_list_free (list);
                list = NULL;
 
-               exc = mono_get_exception_reflection_type_load_checked (res, exl, &error);
-               if (!is_ok (&error)) {
-                       mono_error_set_pending_exception (&error);
-                       return NULL;
+               MONO_HANDLE_ASSIGN (exc, mono_get_exception_reflection_type_load_checked (res, exl, error));
+               if (!is_ok (error)) {
+                       return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
                }
-               mono_set_pending_exception (exc);
-               return NULL;
+               mono_error_set_exception_handle (error, exc);
+               return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
        }
                
        return res;