grammar updates
[mono.git] / mono / metadata / metadata.c
index c6facb3673ce6d77b1c7323da67718a3b1dd3641..0ee805fcc95f6e66015baf7158554294502f5e99 100644 (file)
@@ -1367,6 +1367,7 @@ mono_metadata_parse_method_signature (MonoImage *m, int def, const char *ptr, co
        method->hasthis = hasthis;
        method->explicit_this = explicit_this;
        method->call_convention = call_convention;
+       method->generic_param_count = gen_param_count;
        if (call_convention != 0xa)
                method->ret = mono_metadata_parse_type (m, MONO_PARSE_RET, ret_attrs, ptr, &ptr);
 
@@ -1410,23 +1411,33 @@ mono_metadata_free_method_signature (MonoMethodSignature *sig)
        g_free (sig);
 }
 
-static MonoGenericInst *
-mono_metadata_parse_generic_inst (MonoImage *m, const char *ptr, const char **rptr)
+static void
+do_mono_metadata_parse_generic_inst (MonoType *type, MonoImage *m, const char *ptr, const char **rptr)
 {
        MonoGenericInst *generic_inst = g_new0 (MonoGenericInst, 1);
        int i, count;
+
+       type->data.generic_inst = generic_inst;
        
        generic_inst->generic_type = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
        generic_inst->type_argc = count = mono_metadata_decode_value (ptr, &ptr);
        generic_inst->type_argv = g_new0 (MonoType*, count);
 
+       /*
+        * Create the klass before parsing the type arguments.
+        * This is required to support "recursive" definitions.
+        * See mcs/tests/gen-23.cs for an example.
+        */
+
+       generic_inst->klass = mono_class_create_from_generic (m, type);
+
        for (i = 0; i < generic_inst->type_argc; i++)
                generic_inst->type_argv [i] = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
        
+       mono_class_initialize_generic (generic_inst->klass, TRUE);
+       
        if (rptr)
                *rptr = ptr;
-
-       return generic_inst;
 }
 
 static MonoGenericParam *
@@ -1509,7 +1520,7 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, const char *ptr, cons
                break;
 
        case MONO_TYPE_GENERICINST:
-               type->data.generic_inst = mono_metadata_parse_generic_inst (m, ptr, &ptr);
+               do_mono_metadata_parse_generic_inst (type, m, ptr, &ptr);
                break;
                
        default:
@@ -2272,8 +2283,7 @@ mono_type_size (MonoType *t, gint *align)
                *align = __alignof__(gpointer);
                return sizeof (gpointer);
        case MONO_TYPE_TYPEDBYREF:
-               *align = __alignof__(gpointer);
-               return sizeof (gpointer) * 2;
+               return mono_class_value_size (mono_defaults.typed_reference_class, align);
        case MONO_TYPE_GENERICINST: {
                MonoClass *iclass = mono_class_from_mono_type (t);
                return mono_type_size (&iclass->byval_arg, align);
@@ -2457,7 +2467,7 @@ mono_metadata_type_equal (MonoType *t1, MonoType *t2)
        }
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
-               return t1->data.generic_param == t2->data.generic_param;
+               return t1->data.generic_param->num == t2->data.generic_param->num;
        default:
                g_error ("implement type compare for %0x!", t1->type);
                return FALSE;
@@ -2858,12 +2868,31 @@ mono_type_create_from_typespec (MonoImage *image, guint32 type_spec)
        guint32 len;
        MonoType *type;
 
+       mono_loader_lock ();
+
+       if ((type = g_hash_table_lookup (image->typespec_cache, GUINT_TO_POINTER (type_spec)))) {
+               mono_loader_unlock ();
+               return type;
+       }
+
        t = &image->tables [MONO_TABLE_TYPESPEC];
        
        mono_metadata_decode_row (t, idx-1, cols, MONO_TYPESPEC_SIZE);
        ptr = mono_metadata_blob_heap (image, cols [MONO_TYPESPEC_SIGNATURE]);
        len = mono_metadata_decode_value (ptr, &ptr);
-       type = mono_metadata_parse_type (image, MONO_PARSE_TYPE, 0, ptr, &ptr);
+
+       type = g_new0 (MonoType, 1);
+
+       g_hash_table_insert (image->typespec_cache, GUINT_TO_POINTER (type_spec), type);
+
+       if (*ptr == MONO_TYPE_BYREF) {
+               type->byref = 1; 
+               ptr++;
+       }
+
+       do_mono_metadata_parse_type (type, image, ptr, &ptr);
+
+       mono_loader_unlock ();
 
        return type;
 }
@@ -3234,6 +3263,8 @@ mono_metadata_load_generic_params (MonoImage *image, guint32 token, guint32 *num
        n = 1;
        do {
                params = g_realloc (params, sizeof (MonoGenericParam) * n);
+               params [n - 1].pklass = NULL;
+               params [n - 1].method = NULL;
                params [n - 1].flags = cols [MONO_GENERICPARAM_FLAGS];
                params [n - 1].num = cols [MONO_GENERICPARAM_NUMBER];
                params [n - 1].name = mono_metadata_string_heap (image, cols [MONO_GENERICPARAM_NAME]);