2009-12-16 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mono / metadata / loader.c
index 84befc4a0f462340d5c46d7153b9714716f9f51c..c2eadb7f3da33ac044732f31b637d50d9651a64e 100644 (file)
@@ -585,6 +585,7 @@ find_method_in_class (MonoClass *klass, const char *name, const char *qname, con
                        guint32 cols [MONO_METHOD_SIZE];
                        MonoMethod *method;
                        const char *m_name;
+                       MonoMethodSignature *other_sig;
 
                        mono_metadata_decode_table_row (klass->image, MONO_TABLE_METHOD, klass->method.first + i, cols, MONO_METHOD_SIZE);
 
@@ -596,7 +597,8 @@ find_method_in_class (MonoClass *klass, const char *name, const char *qname, con
                                continue;
 
                        method = mono_get_method (klass->image, MONO_TOKEN_METHOD_DEF | (klass->method.first + i + 1), klass);
-                       if (method && (sig->call_convention != MONO_CALL_VARARG) && mono_metadata_signature_equal (sig, mono_method_signature (method)))
+                       other_sig = mono_method_signature (method);
+                       if (method && other_sig && (sig->call_convention != MONO_CALL_VARARG) && mono_metadata_signature_equal (sig, other_sig))
                                return method;
                }
        }
@@ -990,6 +992,7 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp
 static MonoMethod *
 method_from_methodspec (MonoImage *image, MonoGenericContext *context, guint32 idx)
 {
+       MonoError error;
        MonoMethod *method;
        MonoClass *klass;
        MonoTableInfo *tables = image->tables;
@@ -1014,8 +1017,13 @@ method_from_methodspec (MonoImage *image, MonoGenericContext *context, guint32 i
        g_assert (param_count);
 
        inst = mono_metadata_parse_generic_inst (image, NULL, param_count, ptr, &ptr);
-       if (context && inst->is_open)
-               inst = mono_metadata_inflate_generic_inst (inst, context);
+       if (context && inst->is_open) {
+               inst = mono_metadata_inflate_generic_inst (inst, context, &error);
+               if (!mono_error_ok (&error)) {
+                       mono_error_cleanup (&error); /*FIXME don't swallow error message.*/
+                       return NULL;
+               }
+       }
 
        if ((token & MONO_METHODDEFORREF_MASK) == MONO_METHODDEFORREF_METHODDEF)
                method = mono_get_method_full (image, MONO_TOKEN_METHOD_DEF | nindex, NULL, context);
@@ -1488,6 +1496,8 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass,
 
        if (!klass) { /*FIXME put this before the image alloc*/
                guint32 type = mono_metadata_typedef_from_method (image, token);
+               if (!type)
+                       return NULL;
                klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | type);
                if (klass == NULL)
                        return NULL;
@@ -1553,14 +1563,6 @@ mono_get_method (MonoImage *image, guint32 token, MonoClass *klass)
        return mono_get_method_full (image, token, klass, NULL);
 }
 
-static gpointer
-get_method_token (gpointer value)
-{
-       MonoMethod *m = (MonoMethod*)value;
-
-       return GUINT_TO_POINTER (m->token);
-}
-
 MonoMethod *
 mono_get_method_full (MonoImage *image, guint32 token, MonoClass *klass,
                      MonoGenericContext *context)
@@ -2054,7 +2056,6 @@ mono_method_signature (MonoMethod *m)
        gboolean can_cache_signature;
        MonoGenericContainer *container;
        MonoMethodSignature *signature = NULL;
-       int *pattrs;
        guint32 sig_offset;
 
        /* We need memory barriers below because of the double-checked locking pattern */ 
@@ -2099,11 +2100,8 @@ mono_method_signature (MonoMethod *m)
        can_cache_signature = !(m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) && !(m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) && !container;
 
        /* If the method has parameter attributes, that can modify the signature */
-       pattrs = mono_metadata_get_param_attrs (img, idx);
-       if (pattrs) {
+       if (mono_metadata_method_has_param_attrs (img, idx))
                can_cache_signature = FALSE;
-               g_free (pattrs);
-       }
 
        if (can_cache_signature)
                signature = g_hash_table_lookup (img->method_signatures, sig);
@@ -2132,15 +2130,18 @@ mono_method_signature (MonoMethod *m)
        if (signature->generic_param_count) {
                if (!container || !container->is_method) {
                        g_warning ("Signature claims method has generic parameters, but generic_params table says it doesn't for method 0x%08x from image %s", idx, img->name);
+                       mono_loader_unlock ();
                        return NULL;
                }
                if (container->type_argc != signature->generic_param_count) {
-                       g_warning ("Inconsistent generic parameter count.  Signature says %d, generic_params table says %dfor method 0x%08x from image %s",
+                       g_warning ("Inconsistent generic parameter count.  Signature says %d, generic_params table says %d for method 0x%08x from image %s",
                                 signature->generic_param_count, container->type_argc, idx, img->name);
+                       mono_loader_unlock ();
                        return NULL;
                }
        } else if (container && container->is_method && container->type_argc) {
                g_warning ("generic_params table claims method has generic parameters, but signature says it doesn't for method 0x%08x from image %s", idx, img->name);
+               mono_loader_unlock ();
                return NULL;
        }
        if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)
@@ -2171,6 +2172,7 @@ mono_method_signature (MonoMethod *m)
                case PINVOKE_ATTRIBUTE_CALL_CONV_GENERICINST:
                default:
                        g_warning ("unsupported calling convention : 0x%04x for method 0x%08x from image %s", piinfo->piflags, idx, img->name);
+                       mono_loader_unlock ();
                        return NULL;
                }
                signature->call_convention = conv;
@@ -2247,13 +2249,13 @@ mono_method_get_header (MonoMethod *method)
        idx = mono_metadata_token_index (method->token);
        img = method->klass->image;
        rva = mono_metadata_decode_row_col (&img->tables [MONO_TABLE_METHOD], idx - 1, MONO_METHOD_RVA);
-       loc = mono_image_rva_map (img, rva);
-
-       g_assert (loc);
 
        if (!mono_verifier_verify_method_header (img, rva, NULL))
                return NULL;
 
+       loc = mono_image_rva_map (img, rva);
+       g_assert (loc);
+
        header = mono_metadata_parse_mh_full (img, mono_method_get_generic_container (method), loc);
 
        mono_loader_lock ();