Updated.
[mono.git] / mono / dis / get.c
index 34a7e8d2e9b129c998af0fb3f67ac0b0e9222d04..c1a42a4e39d2fb84f384a5d766b9834685bdd74c 100644 (file)
@@ -169,7 +169,7 @@ get_array_shape (MonoImage *m, const char *ptr, char **result)
  * Returns the stringified representation of a TypeSpec signature (22.2.17)
  */
 char *
-get_typespec (MonoImage *m, guint32 idx, MonoGenericContext *context)
+get_typespec (MonoImage *m, guint32 idx, gboolean is_def, MonoGenericContext *context)
 {
        guint32 cols [MONO_TYPESPEC_SIZE];
        const char *ptr;
@@ -234,15 +234,8 @@ get_typespec (MonoImage *m, guint32 idx, MonoGenericContext *context)
                g_free (s);
                break;
 
-       case MONO_TYPE_VAR:
-       case MONO_TYPE_MVAR:
-               ptr = get_type (m, ptr-1, &s, context);
-               g_string_append (res, s);
-               g_free (s);
-               break;
-               
        default:
-               s = dis_stringify_type (m, type);
+               s = dis_stringify_type (m, type, is_def);
                g_string_append (res, s);
                g_free (s);
                break;
@@ -351,7 +344,7 @@ get_typedef_or_ref (MonoImage *m, guint32 dor_token, MonoGenericContext *context
                break;
                
        case 2: /* TypeSpec */
-               s = get_typespec (m, idx, context);
+               s = get_typespec (m, idx, FALSE, context);
                break;
 
        default:
@@ -476,7 +469,7 @@ dis_stringify_token (MonoImage *m, guint32 token)
        switch (token >> 24) {
        case MONO_TABLE_TYPEDEF: return get_typedef (m, idx);
        case MONO_TABLE_TYPEREF: return get_typeref (m, idx);
-       case MONO_TABLE_TYPESPEC: return get_typespec (m, idx, NULL);
+       case MONO_TABLE_TYPESPEC: return get_typespec (m, idx, FALSE, NULL);
        default:
                 break;
        }
@@ -484,13 +477,13 @@ dis_stringify_token (MonoImage *m, guint32 token)
 }
 
 char*
-dis_stringify_array (MonoImage *m, MonoArrayType *array
+dis_stringify_array (MonoImage *m, MonoArrayType *array, gboolean is_def)
 {
        char *type;
        GString *s = g_string_new("");
        int i;
        
-       type = dis_stringify_type (m, &array->eklass->byval_arg);
+       type = dis_stringify_type (m, &array->eklass->byval_arg, is_def);
        g_string_append (s, type);
        g_free (type);
        g_string_append_c (s, '[');
@@ -538,7 +531,7 @@ dis_stringify_param (MonoImage *m, MonoType *param)
        const char *out = param->attrs & PARAM_ATTRIBUTE_OUT ? "[out]": "";
        const char *opt = param->attrs & PARAM_ATTRIBUTE_OPTIONAL ? "[opt]": "";
        attribs = g_strconcat(out, opt, NULL);
-       t = dis_stringify_type (m, param);
+       t = dis_stringify_type (m, param, TRUE);
        result = g_strjoin(attribs[0] ? " ":"", attribs, t, NULL);
        g_free (t);
        g_free (attribs);
@@ -569,7 +562,9 @@ get_generic_param (MonoImage *m, MonoGenericContainer *container)
        for (i = 0; i < container->type_argc; i++) {
                MonoGenericParam *param = &container->type_params [i];
                MonoClass **constr;
+               int first = 1;
                guint16 flags;
+               char *esname;
 
                if (i > 0)
                        g_string_append (result, ",");
@@ -585,12 +580,22 @@ get_generic_param (MonoImage *m, MonoGenericContainer *container)
                for (constr = param->constraints; constr && *constr; constr++) {
                        char *sig;
 
-                       sig = dis_stringify_object_with_class (m, *constr, FALSE);
-                       g_string_append_printf (result, "(%s) ", sig);
+                       if (first) {
+                               g_string_append_c (result, '(');
+                               first = 0;
+                       } else
+                               g_string_append (result, ", ");
+                       sig = dis_stringify_object_with_class (m, *constr, TRUE, TRUE);
+                       g_string_append (result, sig);
                        g_free (sig);
                 }
 
-               g_string_append (result, param->name);
+               if (!first)
+                       g_string_append (result, ") ");
+
+               esname = get_escaped_name (param->name);
+               g_string_append (result, esname);
+               g_free (esname);
        }
 
        g_string_append_c (result, '>');
@@ -627,19 +632,19 @@ dis_stringify_method_signature (MonoImage *m, MonoMethodSignature *method, int m
                if (!method) {
                        const char *sig = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]);
 
-                       container = mono_metadata_load_generic_params (m, MONO_TOKEN_METHOD_DEF | methoddef_row);
-                       if (container) {
-                               container->parent = context ? context->container : NULL;
-                               container->is_method = 1;
-
+                       container = mono_metadata_load_generic_params (
+                               m, MONO_TOKEN_METHOD_DEF | methoddef_row, context ? context->container : NULL);
+                       if (container)
                                context = (MonoGenericContext *) container;
-                       }
 
                        mono_metadata_decode_blob_size (sig, &sig);
                        method = mono_metadata_parse_method_signature_full (m, context, methoddef_row, sig, &sig);
                        free_method = 1;
-               }      
-                gen_param = get_generic_param (m, container);
+               } else if (context)
+                       container = context->container;
+
+               if (container && container->is_method)
+                       gen_param = get_generic_param (m, container);
        }
        
        retval = dis_stringify_param (m, method->ret);
@@ -724,24 +729,28 @@ dis_stringify_function_ptr (MonoImage *m, MonoMethodSignature *method)
 }
 
 static char *
-get_class_name (MonoClass *c)
+get_escaped_class_name (MonoClass *c)
 {
+       char *result, *esname;
+
+       esname = get_escaped_name (c->name);
+
        if (c->nested_in){
-               char *part_a = get_class_name (c->nested_in);
-               char *result;
+               char *part_a = get_escaped_class_name (c->nested_in);
 
-               result = g_strdup_printf ("%s/%s", part_a, c->name);
+               result = g_strdup_printf ("%s/%s", part_a, esname);
                g_free (part_a);
-               return result;
-       }
-       if (*c->name_space)
-               return g_strdup_printf ("%s.%s", c->name_space, c->name);
+       } else if (*c->name_space)
+               result = g_strdup_printf ("%s.%s", c->name_space, esname);
        else
-               return g_strdup (c->name);
+               result = g_strdup (esname);
+
+       g_free (esname);
+       return result;
 }
 
 char *
-dis_stringify_object_with_class (MonoImage *m, MonoClass *c, gboolean prefix)
+dis_stringify_object_with_class (MonoImage *m, MonoClass *c, gboolean prefix, gboolean is_def)
 {
        /* FIXME: handle MONO_TYPE_OBJECT ... */
        const char *otype = c->byval_arg.type == MONO_TYPE_VALUETYPE ? "valuetype " : "class " ;
@@ -763,10 +772,7 @@ dis_stringify_object_with_class (MonoImage *m, MonoClass *c, gboolean prefix)
                }
        }
 
-       result = get_class_name (c);
-       
-       esname = get_escaped_name (result);
-       g_free (result);
+       esname = get_escaped_class_name (c);
 
        if (c->generic_class) {
                MonoGenericClass *gclass = c->generic_class;
@@ -774,7 +780,7 @@ dis_stringify_object_with_class (MonoImage *m, MonoClass *c, gboolean prefix)
                int i;
 
                for (i = 0; i < gclass->inst->type_argc; i++){
-                       char *t = dis_stringify_type (m, gclass->inst->type_argv [i]);
+                       char *t = dis_stringify_type (m, gclass->inst->type_argv [i], is_def);
 
                        g_string_append (str, t);
                        if (i+1 != gclass->inst->type_argc)
@@ -797,14 +803,14 @@ dis_stringify_object_with_class (MonoImage *m, MonoClass *c, gboolean prefix)
 }
 
 static char *
-dis_stringify_object (MonoImage *m, MonoType *type)
+dis_stringify_object (MonoImage *m, MonoType *type, gboolean is_def)
 {
        MonoClass *c = mono_class_from_mono_type (type);
-       return dis_stringify_object_with_class (m, c, TRUE);
+       return dis_stringify_object_with_class (m, c, TRUE, is_def);
 }
 
 char*
-dis_stringify_type (MonoImage *m, MonoType *type)
+dis_stringify_type (MonoImage *m, MonoType *type, gboolean is_def)
 {
        const char *pinned = "", *byref = "";
        char *bare = NULL, *mods = NULL;
@@ -836,7 +842,7 @@ dis_stringify_type (MonoImage *m, MonoType *type)
                
        case MONO_TYPE_VALUETYPE:
        case MONO_TYPE_CLASS:
-               bare = dis_stringify_object (m, type);
+               bare = dis_stringify_object (m, type, is_def);
                break;
        case MONO_TYPE_FNPTR: {
                char *child_type;
@@ -847,7 +853,7 @@ dis_stringify_type (MonoImage *m, MonoType *type)
        }
        case MONO_TYPE_PTR: {
                char *child_type;
-               child_type = dis_stringify_type (m, type->data.type);
+               child_type = dis_stringify_type (m, type->data.type, is_def);
                
                bare = g_strdup_printf ("%s*", child_type);
                g_free (child_type);
@@ -855,33 +861,40 @@ dis_stringify_type (MonoImage *m, MonoType *type)
        }
        case MONO_TYPE_SZARRAY: {
                char *child_type;
-               child_type = dis_stringify_type (m, &type->data.klass->byval_arg);
+               child_type = dis_stringify_type (m, &type->data.klass->byval_arg, is_def);
                
                bare = g_strdup_printf ("%s[]", child_type);
                g_free (child_type);
                break;
        }
        case MONO_TYPE_ARRAY:
-               bare = dis_stringify_array (m, type->data.array);
+               bare = dis_stringify_array (m, type->data.array, is_def);
                break;
        case MONO_TYPE_VOID:
                bare = g_strdup ("void");
                break;
        case MONO_TYPE_MVAR:
-               g_assert (type->data.generic_param->name);
-               bare = g_strdup_printf ("!!%s", type->data.generic_param->name);
+               if (is_def) {
+                       g_assert (type->data.generic_param->name);
+                       bare = g_strdup_printf ("!!%s", type->data.generic_param->name);
+               } else
+                       bare = g_strdup_printf ("!!%d", type->data.generic_param->num);
                break;
        case MONO_TYPE_VAR:
-               g_assert (type->data.generic_param->name);
-               bare = g_strdup_printf ("!%s", type->data.generic_param->name);
+               if (is_def) {
+                       g_assert (type->data.generic_param->name);
+                       bare = g_strdup_printf ("!%s", type->data.generic_param->name);
+               } else
+                       bare = g_strdup_printf ("!%d", type->data.generic_param->num);
                break;
        case MONO_TYPE_GENERICINST: {
                GString *str = g_string_new ("");
                int i;
-               char *generic_type = dis_stringify_type (m, type->data.generic_class->generic_type);
+               char *generic_type = dis_stringify_type (
+                       m, &type->data.generic_class->container_class->byval_arg, is_def);
 
                for (i = 0; i < type->data.generic_class->inst->type_argc; i++){
-                       char *t = dis_stringify_type (m, type->data.generic_class->inst->type_argv [i]);
+                       char *t = dis_stringify_type (m, type->data.generic_class->inst->type_argv [i], is_def);
 
                        g_string_append (str, t);
                        if (i+1 != type->data.generic_class->inst->type_argc)
@@ -938,7 +951,7 @@ get_type (MonoImage *m, const char *ptr, char **result, MonoGenericContext *cont
        case MONO_TYPE_CLASS: {
                guint32 token = mono_metadata_parse_typedef_or_ref (m, ptr, &ptr);
                MonoClass *klass = mono_class_get (m, token);
-               char *temp = dis_stringify_object_with_class (m, klass, TRUE);
+               char *temp = dis_stringify_object_with_class (m, klass, TRUE, FALSE);
 
                if (show_tokens) {
                        *result = g_strdup_printf ("%s/*%08x*/", temp, token);
@@ -975,7 +988,7 @@ get_type (MonoImage *m, const char *ptr, char **result, MonoGenericContext *cont
 
        default:
                t = mono_metadata_parse_type_full (m, context, MONO_PARSE_TYPE, 0, start, &ptr);
-               *result = dis_stringify_type (m, t);
+               *result = dis_stringify_type (m, t, FALSE);
                mono_metadata_free_type (t);
                break;
        }
@@ -1162,7 +1175,21 @@ get_escaped_name (const char *name)
                return g_strdup (name);
 
        for (s = name; *s; s++) {
-               if (isalnum (*s) || *s == '_' || *s == '$' || *s == '@' || *s == '?' || *s == '.' || *s == 0)
+               char *first, *result;
+
+               if (*s != '/')
+                       continue;
+
+               first = g_strndup (name, s-name);
+               result = g_strdup_printf ("%s/%s", get_escaped_name (first), get_escaped_name (s+1));
+               g_free (first);
+
+               return result;
+       }
+
+       for (s = name; *s; s++) {
+               if (isalnum (*s) || *s == '_' || *s == '$' || *s == '@' ||
+                   *s == '?' || *s == '.' || *s == 0 || *s == '!')
                        continue;
 
                return g_strdup_printf ("'%s'", name);
@@ -1408,7 +1435,7 @@ get_memberref_context (MonoImage *m, guint32 mrp_token, MonoGenericContext *cont
        switch (table){
        case 0: /* TypeDef */
                return (MonoGenericContext *) mono_metadata_load_generic_params (
-                       m, MONO_TOKEN_TYPE_DEF | idx);
+                       m, MONO_TOKEN_TYPE_DEF | idx, NULL);
                
        case 1: /* TypeRef */
                return NULL;
@@ -1445,7 +1472,7 @@ get_memberref_parent (MonoImage *m, guint32 mrp_token, MonoGenericContext *conte
                return g_strdup ("TODO:MethodDef");
                
        case 4: /* TypeSpec */
-               return get_typespec (m, idx, context);
+               return get_typespec (m, idx, FALSE, context);
        }
        g_assert_not_reached ();
        return NULL;
@@ -1475,7 +1502,7 @@ get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericConte
                if (mh->signature->is_inflated)
                        context = ((MonoMethodInflated *) mh)->context;
                esname = get_escaped_name (mh->name);
-               sig = dis_stringify_object_with_class (m, mh->klass, TRUE);
+               sig = dis_stringify_object_with_class (m, mh->klass, TRUE, TRUE);
                if (show_tokens)
                        name = g_strdup_printf ("%s/*%08x*/::%s", sig, token, esname);
                else
@@ -1555,7 +1582,7 @@ get_methoddef (MonoImage *m, guint32 idx)
 
        mh = mono_get_method (m, MONO_TOKEN_METHOD_DEF | idx, NULL);
        if (mh) {
-               sig = dis_stringify_object_with_class (m, mh->klass, TRUE);
+               sig = dis_stringify_object_with_class (m, mh->klass, TRUE, FALSE);
                name = g_strdup_printf ("%s::%s", sig, mh->name);
                g_free (sig);
        } else
@@ -1817,11 +1844,14 @@ get_token (MonoImage *m, guint32 token, MonoGenericContext *context)
                g_free (temp);
                return result;
        case MONO_TOKEN_TYPE_DEF:
-               return get_typedef (m, idx);
+               temp = get_typedef (m, idx);
+               result = get_escaped_name (temp);
+               g_free (temp);
+               return result;
        case MONO_TOKEN_TYPE_REF:
                return get_typeref (m, idx);
        case MONO_TOKEN_TYPE_SPEC:
-               return get_typespec (m, idx, context);
+               return get_typespec (m, idx, TRUE, context);
        case MONO_TOKEN_MEMBER_REF: {
                guint32 cols [MONO_MEMBERREF_SIZE];
                const char *sig;
@@ -1876,7 +1906,7 @@ get_token_type (MonoImage *m, guint32 token, MonoGenericContext *context)
                break;
                
        case MONO_TOKEN_TYPE_SPEC:
-               s = get_typespec (m, idx, context);
+               s = get_typespec (m, idx, FALSE, context);
                break;
 
        default:
@@ -2435,6 +2465,7 @@ init_key_table (void)
        g_hash_table_insert (key_table, (char *) "stored_object", GINT_TO_POINTER (TRUE));
        g_hash_table_insert (key_table, (char *) "streamed_object", GINT_TO_POINTER (TRUE));
        g_hash_table_insert (key_table, (char *) "stream", GINT_TO_POINTER (TRUE));
+       g_hash_table_insert (key_table, (char *) "strict", GINT_TO_POINTER (TRUE));
        g_hash_table_insert (key_table, (char *) "string", GINT_TO_POINTER (TRUE));
        g_hash_table_insert (key_table, (char *) "struct", GINT_TO_POINTER (TRUE));
        g_hash_table_insert (key_table, (char *) "synchronized", GINT_TO_POINTER (TRUE));
@@ -2445,6 +2476,7 @@ init_key_table (void)
        g_hash_table_insert (key_table, (char *) "tls", GINT_TO_POINTER (TRUE));
        g_hash_table_insert (key_table, (char *) "to", GINT_TO_POINTER (TRUE));
        g_hash_table_insert (key_table, (char *) "true", GINT_TO_POINTER (TRUE));
+       g_hash_table_insert (key_table, (char *) "type", GINT_TO_POINTER (TRUE));
        g_hash_table_insert (key_table, (char *) "typedref", GINT_TO_POINTER (TRUE));
        g_hash_table_insert (key_table, (char *) "unicode", GINT_TO_POINTER (TRUE));
        g_hash_table_insert (key_table, (char *) "unmanagedexp", GINT_TO_POINTER (TRUE));