[reflection] Add MonoError-ized mono_reflection_get_type_checked
authorAleksey Kliger <aleksey@xamarin.com>
Fri, 4 Mar 2016 17:52:41 +0000 (12:52 -0500)
committerAleksey Kliger <aleksey@xamarin.com>
Wed, 9 Mar 2016 16:10:32 +0000 (11:10 -0500)
Mark mono_reflection_get_type external only.

mono/metadata/icall.c
mono/metadata/reflection-internals.h
mono/metadata/reflection.c
mono/metadata/reflection.h
mono/mini/debugger-agent.c

index ef84dcb9d7f92d757b67a7685c8224aec3bbbe0f..48a09e56c0240d511c492bcdeaaf8220ee429398 100644 (file)
@@ -1364,15 +1364,19 @@ type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoErro
 
        if (assembly) {
                /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */
-               type = mono_reflection_get_type (assembly->image, info, ignoreCase, &type_resolve);
+               type = mono_reflection_get_type_checked (assembly->image, info, ignoreCase, &type_resolve, error);
+               return_val_if_nok (error, NULL);
        }
 
-       if (!info->assembly.name && !type) /* try mscorlib */
-               type = mono_reflection_get_type (NULL, info, ignoreCase, &type_resolve);
-
+       if (!info->assembly.name && !type) {
+               /* try mscorlib */
+               type = mono_reflection_get_type_checked (NULL, info, ignoreCase, &type_resolve, error);
+               return_val_if_nok (error, NULL);
+       }
        if (assembly && !type && type_resolve) {
                type_resolve = FALSE; /* This will invoke TypeResolve if not done in the first 'if' */
-               type = mono_reflection_get_type (assembly->image, info, ignoreCase, &type_resolve);
+               type = mono_reflection_get_type_checked (assembly->image, info, ignoreCase, &type_resolve, error);
+               return_val_if_nok (error, NULL);
        }
 
        if (!type) 
@@ -4394,9 +4398,15 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
        }
 
        if (module != NULL) {
-               if (module->image)
-                       type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
-               else
+               if (module->image) {
+                       type = mono_reflection_get_type_checked (module->image, &info, ignoreCase, &type_resolve, &error);
+                       if (!is_ok (&error)) {
+                               g_free (str);
+                               mono_reflection_free_type_info (&info);
+                               mono_error_set_pending_exception (&error);
+                               return NULL;
+                       }
+               } else
                        type = NULL;
        }
        else
@@ -4409,7 +4419,13 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
                        if (abuilder->modules) {
                                for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
                                        MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
-                                       type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
+                                       type = mono_reflection_get_type_checked (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve, &error);
+                                       if (!is_ok (&error)) {
+                                               g_free (str);
+                                               mono_reflection_free_type_info (&info);
+                                               mono_error_set_pending_exception (&error);
+                                               return NULL;
+                                       }
                                        if (type)
                                                break;
                                }
@@ -4418,14 +4434,27 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
                        if (!type && abuilder->loaded_modules) {
                                for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
                                        MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
-                                       type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
+                                       type = mono_reflection_get_type_checked (mod->image, &info, ignoreCase, &type_resolve, &error);
+                                       if (!is_ok (&error)) {
+                                               g_free (str);
+                                               mono_reflection_free_type_info (&info);
+                                               mono_error_set_pending_exception (&error);
+                                               return NULL;
+                                       }
                                        if (type)
                                                break;
                                }
                        }
                }
-               else
-                       type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
+               else {
+                       type = mono_reflection_get_type_checked (assembly->assembly->image, &info, ignoreCase, &type_resolve, &error);
+                       if (!is_ok (&error)) {
+                               g_free (str);
+                               mono_reflection_free_type_info (&info);
+                               mono_error_set_pending_exception (&error);
+                               return NULL;
+                       }
+               }
        g_free (str);
        mono_reflection_free_type_info (&info);
        if (!type) {
@@ -4465,7 +4494,7 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
 
        /* g_print ("got it\n"); */
        ret = mono_type_get_object_checked (mono_object_domain (assembly), type, &error);
-       mono_error_raise_exception (&error);
+       mono_error_set_pending_exception (&error);
 
        return ret;
 }
index 7475f4df10816501a94f89f29f04b82606ef0515..4b4c8a11be4274acd9250d58b0b401c4acc5bc1a 100644 (file)
@@ -8,6 +8,9 @@
 #include <mono/utils/mono-compiler.h>
 #include <mono/utils/mono-error.h>
 
+MonoType*
+mono_reflection_get_type_checked (MonoImage* image, MonoTypeNameParse *info, mono_bool ignorecase, mono_bool *type_resolve, MonoError *error);
+
 MonoType*
 mono_reflection_type_from_name_checked (char *name, MonoImage *image, MonoError *error);
 
index c02f89e7f4427c3d1e6da5a30c5cd0b0c1088de4..e84982d5d76c756ab60da1305c3c4bd08caa0212 100644 (file)
@@ -7802,7 +7802,7 @@ mono_method_body_get_object_checked (MonoDomain *domain, MonoMethod *method, Mon
 
        /* for compatibility with .net */
        if (method_is_dynamic (method)) {
-               mono_error_set_instance (error, mono_get_exception_invalid_operation (NULL));
+               mono_error_set_exception_instance (error, mono_get_exception_invalid_operation (NULL));
                return NULL;
        }
 
@@ -8610,11 +8610,29 @@ mono_reflection_get_type_internal (MonoImage *rootimage, MonoImage* image, MonoT
 MonoType*
 mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve) {
        MonoError error;
-       MonoType *result = mono_reflection_get_type_with_rootimage(image, image, info, ignorecase, type_resolve, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       MonoType *result = mono_reflection_get_type_with_rootimage (image, image, info, ignorecase, type_resolve, &error);
+       mono_error_cleanup (&error);
        return result;
 }
 
+/**
+ * mono_reflection_get_type_checked:
+ * @image: a metadata context
+ * @info: type description structure
+ * @ignorecase: flag for case-insensitive string compares
+ * @type_resolve: whenever type resolve was already tried
+ * @error: set on error.
+ *
+ * Build a MonoType from the type description in @info. On failure returns NULL and sets @error.
+ *
+ */
+MonoType*
+mono_reflection_get_type_checked (MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve, MonoError *error) {
+       mono_error_init (error);
+       return mono_reflection_get_type_with_rootimage (image, image, info, ignorecase, type_resolve, error);
+}
+
+
 static MonoType*
 mono_reflection_get_type_internal_dynamic (MonoImage *rootimage, MonoAssembly *assembly, MonoTypeNameParse *info, gboolean ignorecase, MonoError *error)
 {
index 87a49d1563a7c33a24d1ce9a145ba7746d6312ab..ae234421f8b3572ba0ada0d67c648b41c8d16a9f 100644 (file)
@@ -42,6 +42,7 @@ typedef enum {
 } MonoResolveTokenError;
 
 MONO_API int           mono_reflection_parse_type (char *name, MonoTypeNameParse *info);
+MONO_RT_EXTERNAL_ONLY
 MONO_API MonoType*     mono_reflection_get_type   (MonoImage* image, MonoTypeNameParse *info, mono_bool ignorecase, mono_bool *type_resolve);
 MONO_API void          mono_reflection_free_type_info (MonoTypeNameParse *info);
 MONO_RT_EXTERNAL_ONLY
index 140fbfb689b1f89ea0ef61570ed56b0c51bf9c01..4c791507cc3775777fb5e32e80d057292f1841e0 100644 (file)
@@ -7246,8 +7246,11 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
                                ass = (MonoAssembly *)tmp->data;
 
                                if (ass->image) {
+                                       MonoError error;
                                        type_resolve = TRUE;
-                                       t = mono_reflection_get_type (ass->image, &info, ignore_case, &type_resolve);
+                                       /* FIXME really okay to call while holding locks? */
+                                       t = mono_reflection_get_type_checked (ass->image, &info, ignore_case, &type_resolve, &error);
+                                       mono_error_cleanup (&error); 
                                        if (t) {
                                                g_ptr_array_add (res_classes, mono_type_get_class (t));
                                                g_ptr_array_add (res_domains, domain);
@@ -7663,6 +7666,7 @@ assembly_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                break;
        }
        case CMD_ASSEMBLY_GET_TYPE: {
+               MonoError error;
                char *s = decode_string (p, &p, end);
                gboolean ignorecase = decode_byte (p, &p, end);
                MonoTypeNameParse info;
@@ -7679,7 +7683,13 @@ assembly_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                } else {
                        if (info.assembly.name)
                                NOT_IMPLEMENTED;
-                       t = mono_reflection_get_type (ass->image, &info, ignorecase, &type_resolve);
+                       t = mono_reflection_get_type_checked (ass->image, &info, ignorecase, &type_resolve, &error);
+                       if (!is_ok (&error)) {
+                               mono_error_cleanup (&error); /* FIXME don't swallow the error */
+                               mono_reflection_free_type_info (&info);
+                               g_free (s);
+                               return ERR_INVALID_ARGUMENT;
+                       }
                }
                buffer_add_typeid (buf, domain, t ? mono_class_from_mono_type (t) : NULL);
                mono_reflection_free_type_info (&info);