[runtime] Introduce mono_method_get_signature_checked as the MonoError variant of...
authorRodrigo Kumpera <kumpera@gmail.com>
Tue, 18 Nov 2014 21:24:51 +0000 (16:24 -0500)
committerRodrigo Kumpera <kumpera@gmail.com>
Tue, 18 Nov 2014 21:51:06 +0000 (16:51 -0500)
mono/metadata/loader.c
mono/metadata/metadata-internals.h
mono/metadata/object-internals.h
mono/metadata/reflection.c

index ab56e350999350f2c97a40ab3cf7c5e06e390e47..c7367e193602cdacf44dc90645cf5da1e75506eb 100644 (file)
@@ -868,6 +868,22 @@ inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context)
  */
 MonoMethodSignature*
 mono_method_get_signature_full (MonoMethod *method, MonoImage *image, guint32 token, MonoGenericContext *context)
+{
+       MonoError error;
+       MonoMethodSignature *res = mono_method_get_signature_checked (method, image, token, context, &error);
+
+       g_assert (!mono_loader_get_last_error ());
+
+       if (!res) {
+               g_assert (!mono_error_ok (&error));
+               mono_loader_set_error_from_mono_error (&error);
+               mono_error_cleanup (&error); /* FIXME Don't swallow the error */
+       }
+       return res;
+}
+
+MonoMethodSignature*
+mono_method_get_signature_checked (MonoMethod *method, MonoImage *image, guint32 token, MonoGenericContext *context, MonoError *error)
 {
        int table = mono_metadata_token_table (token);
        int idx = mono_metadata_token_index (token);
@@ -876,23 +892,27 @@ mono_method_get_signature_full (MonoMethod *method, MonoImage *image, guint32 to
        MonoMethodSignature *sig;
        const char *ptr;
 
+       mono_error_init (error);
+
        /* !table is for wrappers: we should really assign their own token to them */
        if (!table || table == MONO_TABLE_METHOD)
-               return mono_method_signature (method);
+               return mono_method_signature_checked (method, error);
 
        if (table == MONO_TABLE_METHODSPEC) {
                /* the verifier (do_invoke_method) will turn the NULL into a verifier error */
                if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || !method->is_inflated)
                        return NULL;
 
-               return mono_method_signature (method);
+               return mono_method_signature_checked (method, error);
        }
 
        if (method->klass->generic_class)
-               return mono_method_signature (method);
+               return mono_method_signature_checked (method, error);
 
        if (image_is_dynamic (image)) {
-               sig = mono_reflection_lookup_signature (image, method, token);
+               sig = mono_reflection_lookup_signature (image, method, token, error);
+               if (!sig)
+                       return NULL;
        } else {
                mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], idx-1, cols, MONO_MEMBERREF_SIZE);
                sig_idx = cols [MONO_MEMBERREF_SIGNATURE];
@@ -903,15 +923,24 @@ mono_method_get_signature_full (MonoMethod *method, MonoImage *image, guint32 to
                                guint32 class = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK;
                                const char *fname = mono_metadata_string_heap (image, cols [MONO_MEMBERREF_NAME]);
 
-                               mono_loader_set_error_bad_image (g_strdup_printf ("Bad method signature class token 0x%08x field name %s token 0x%08x on image %s", class, fname, token, image->name));
+                               //FIXME include the verification error
+                               mono_error_set_bad_image (error, image, "Bad method signature class token 0x%08x field name %s token 0x%08x", class, fname, token);
                                return NULL;
                        }
 
                        ptr = mono_metadata_blob_heap (image, sig_idx);
                        mono_metadata_decode_blob_size (ptr, &ptr);
+                       /* FIXME make type/signature parsing not produce loader errors */
                        sig = mono_metadata_parse_method_signature (image, 0, ptr, NULL);
-                       if (!sig)
+                       g_assert (!mono_loader_get_last_error ());
+
+                       if (!sig) {
+                               guint32 class = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK;
+                               const char *fname = mono_metadata_string_heap (image, cols [MONO_MEMBERREF_NAME]);
+                               //FIXME include the decoding error
+                               mono_error_set_bad_image (error, image, "Bad method signature class token 0x%08x field name %s token 0x%08x", class, fname, token);
                                return NULL;
+                       }
                        sig = cache_memberref_sig (image, sig_idx, sig);
                }
                /* FIXME: we probably should verify signature compat in the dynamic case too*/
@@ -919,22 +948,18 @@ mono_method_get_signature_full (MonoMethod *method, MonoImage *image, guint32 to
                        guint32 class = cols [MONO_MEMBERREF_CLASS] & MONO_MEMBERREF_PARENT_MASK;
                        const char *fname = mono_metadata_string_heap (image, cols [MONO_MEMBERREF_NAME]);
 
-                       mono_loader_set_error_bad_image (g_strdup_printf ("Incompatible method signature class token 0x%08x field name %s token 0x%08x on image %s", class, fname, token, image->name));
+                       mono_error_set_bad_image (error, image, "Incompatible method signature class token 0x%08x field name %s token 0x%08x", class, fname, token);
                        return NULL;
                }
        }
 
        if (context) {
-               MonoError error;
                MonoMethodSignature *cached;
 
                /* This signature is not owned by a MonoMethod, so need to cache */
-               sig = inflate_generic_signature_checked (image, sig, context, &error);
-               if (!mono_error_ok (&error)) {/*XXX bubble up this and kill one use of loader errors */
-                       mono_loader_set_error_bad_image (g_strdup_printf ("Could not inflate signature %s", mono_error_get_message (&error)));
-                       mono_error_cleanup (&error);
+               sig = inflate_generic_signature_checked (image, sig, context, error);
+               if (!mono_error_ok (error))
                        return NULL;
-               }
 
                cached = mono_metadata_get_inflated_signature (sig, context);
                if (cached != sig)
@@ -944,6 +969,7 @@ mono_method_get_signature_full (MonoMethod *method, MonoImage *image, guint32 to
                sig = cached;
        }
 
+       g_assert (mono_error_ok (error));
        return sig;
 }
 
index a5c8991744564878e1c6a1f736c128d8d3947801..ea35f5b7c636a7b4f7cf08313a6e0f81ac7389fe 100644 (file)
@@ -804,5 +804,9 @@ MonoAotCacheConfig *mono_get_aot_cache_config (void) MONO_INTERNAL;
 MonoType *
 mono_type_create_from_typespec_checked (MonoImage *image, guint32 type_spec, MonoError *error) MONO_INTERNAL;
 
+MonoMethodSignature*
+mono_method_get_signature_checked (MonoMethod *method, MonoImage *image, guint32 token, MonoGenericContext *context, MonoError *error) MONO_INTERNAL;
+       
+
 #endif /* __MONO_METADATA_INTERNALS_H__ */
 
index b690e783e22404704387398628d6827acfdff2af..0e24c963d0c84b0bf5110eb3c89bf04b0db10299 100644 (file)
@@ -1415,7 +1415,7 @@ void        mono_reflection_create_unmanaged_type (MonoReflectionType *type) MON
 void        mono_reflection_register_with_runtime (MonoReflectionType *type) MONO_INTERNAL;
 
 void        mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoArray **typed_args, MonoArray **named_args, CattrNamedArg **named_arg_info, MonoError *error) MONO_INTERNAL;
-MonoMethodSignature * mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token) MONO_INTERNAL;
+MonoMethodSignature * mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error) MONO_INTERNAL;
 
 MonoArray* mono_param_get_objects_internal  (MonoDomain *domain, MonoMethod *method, MonoClass *refclass) MONO_INTERNAL;
 
index 6614b01e1e9863aec5a44153b0f9b5c85365b290..0db16c92df451fbe4c2930a858ceffde31e7b91c 100644 (file)
@@ -11847,16 +11847,18 @@ mono_reflection_is_valid_dynamic_token (MonoDynamicImage *image, guint32 token)
 }
 
 MonoMethodSignature *
-mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token)
+mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token, MonoError *error)
 {
        MonoMethodSignature *sig;
        g_assert (image_is_dynamic (image));
 
+       mono_error_init (error);
+
        sig = g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
        if (sig)
                return sig;
 
-       return mono_method_signature (method);
+       return mono_method_signature_checked (method, error);
 }
 
 #ifndef DISABLE_REFLECTION_EMIT