2009-02-03 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / dis / get.c
index ff8fa9714130dfdc3b3d32f81cbcff15af2a8c6d..3c629bb9891641c664de8d9e9ffd4cfe56a0cf70 100644 (file)
 
 extern gboolean substitute_with_mscorlib_p;
 
-static MonoGenericContext *
-get_memberref_context (MonoImage *m, guint32 mrp_token, MonoGenericContext *context);
+static MonoGenericContainer *
+get_memberref_container (MonoImage *m, guint32 mrp_token, MonoGenericContainer *container);
 
 static char *
-get_memberref_parent (MonoImage *m, guint32 mrp_token, MonoGenericContext *context);
+get_memberref_parent (MonoImage *m, guint32 mrp_token, MonoGenericContainer *container);
  
 static gboolean
 cant_print_generic_param_name (MonoGenericParam *gparam);
@@ -45,6 +45,10 @@ get_typedef (MonoImage *m, int idx)
        char *tstring, *result;
         guint32 token;
         
+       if (idx == 1)
+               /* <Module> */
+               return NULL;
+
        mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPEDEF], idx - 1, cols, MONO_TYPEDEF_SIZE);
 
         ns = mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAMESPACE]);
@@ -88,7 +92,7 @@ get_module (MonoImage *m, int idx)
            
        mono_metadata_decode_row (&m->tables [MONO_TABLE_MODULE], idx - 1, cols, MONO_MODULE_SIZE);
 
-       return g_strdup (mono_metadata_string_heap (m, cols [MONO_MODULE_NAME]));
+       return get_escaped_name (mono_metadata_string_heap (m, cols [MONO_MODULE_NAME]));
 }
 
 char *
@@ -98,7 +102,7 @@ get_moduleref (MonoImage *m, int idx)
        
        mono_metadata_decode_row (&m->tables [MONO_TABLE_MODULEREF], idx - 1, cols, MONO_MODULEREF_SIZE);
 
-       return g_strdup (mono_metadata_string_heap (m, cols [MONO_MODULEREF_NAME]));
+       return get_escaped_name (mono_metadata_string_heap (m, cols [MONO_MODULEREF_NAME]));
 }
 
 char *
@@ -108,7 +112,7 @@ get_assemblyref (MonoImage *m, int idx)
        
        mono_metadata_decode_row (&m->tables [MONO_TABLE_ASSEMBLYREF], idx - 1, cols, MONO_ASSEMBLYREF_SIZE);
 
-       return g_strdup (mono_metadata_string_heap (m, cols [MONO_ASSEMBLYREF_NAME]));
+       return get_escaped_name (mono_metadata_string_heap (m, cols [MONO_ASSEMBLYREF_NAME]));
 }
 
 static char *
@@ -178,7 +182,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, gboolean is_def, MonoGenericContext *context)
+get_typespec (MonoImage *m, guint32 idx, gboolean is_def, MonoGenericContainer *container)
 {
        guint32 cols [MONO_TYPESPEC_SIZE];
        const char *ptr;
@@ -203,7 +207,7 @@ get_typespec (MonoImage *m, guint32 idx, gboolean is_def, MonoGenericContext *co
                if (*ptr == MONO_TYPE_VOID)
                        g_string_append (res, "void");
                else {
-                       ptr = get_type (m, ptr, &s, is_def, context);
+                       ptr = get_type (m, ptr, &s, is_def, container);
                        if (s)
                                g_string_append (res, s);
                }
@@ -211,7 +215,7 @@ get_typespec (MonoImage *m, guint32 idx, gboolean is_def, MonoGenericContext *co
                break;
 
        case MONO_TYPE_FNPTR:
-               sig = mono_metadata_parse_method_signature_full (m, context ? context->container : NULL, 0, ptr, &ptr);
+               sig = mono_metadata_parse_method_signature_full (m, container, 0, ptr, &ptr);
                s = dis_stringify_function_ptr (m, sig);
                g_string_append (res, "method ");
                g_string_append (res, s);
@@ -219,7 +223,7 @@ get_typespec (MonoImage *m, guint32 idx, gboolean is_def, MonoGenericContext *co
                break;
 
        case MONO_TYPE_ARRAY:
-               ptr = get_type (m, ptr, &s, is_def, context);
+               ptr = get_type (m, ptr, &s, is_def, container);
                g_string_append (res, s);
                g_free (s);
                g_string_append_c (res, ' ');
@@ -235,14 +239,14 @@ get_typespec (MonoImage *m, guint32 idx, gboolean is_def, MonoGenericContext *co
                        g_string_append_c (res, ' ');
                        g_free (s);
                }
-               ptr = get_type (m, ptr, &s, is_def, context);
+               ptr = get_type (m, ptr, &s, is_def, container);
                g_string_append (res, s);
                g_string_append (res, "[]");
                g_free (s);
                break;
 
        default:
-               ptr = get_type (m, ptr - 1, &s, is_def, context);
+               ptr = get_type (m, ptr - 1, &s, is_def, container);
                g_string_append (res, s);
                g_free (s);
                break;
@@ -328,7 +332,7 @@ get_typeref (MonoImage *m, int idx)
  * at (dor_token >> 2) 
  */
 char *
-get_typedef_or_ref (MonoImage *m, guint32 dor_token, MonoGenericContext *context)
+get_typedef_or_ref (MonoImage *m, guint32 dor_token, MonoGenericContainer *container)
 {
        char *temp = NULL, *s = NULL;
        int table, idx;
@@ -351,7 +355,7 @@ get_typedef_or_ref (MonoImage *m, guint32 dor_token, MonoGenericContext *context
                break;
                
        case 2: /* TypeSpec */
-               s = get_typespec (m, idx, FALSE, context);
+               s = get_typespec (m, idx, FALSE, container);
                break;
 
        default:
@@ -417,19 +421,19 @@ const char *
 get_custom_mod (MonoImage *m, const char *ptr, char **return_value)
 {
        char *s;
-       const char *reqd;
+       const char *mod;
        
        *return_value = NULL;
        while ((*ptr == MONO_TYPE_CMOD_OPT) ||
                   (*ptr == MONO_TYPE_CMOD_REQD)) {
-               reqd = (*ptr == MONO_TYPE_CMOD_REQD) ? "reqd" : "opt";
+               mod = (*ptr == MONO_TYPE_CMOD_REQD) ? "modreq" : "modopt";
                ptr++;
                ptr = get_encoded_typedef_or_ref (m, ptr, &s);
 
                if (*return_value == NULL)
-                       *return_value = g_strconcat (reqd, " ", s, NULL);
+                       *return_value = g_strconcat (" ", mod, " (", s, ")", NULL);
                else
-                       *return_value = g_strconcat (*return_value, " ", reqd, " ", s, NULL);
+                       *return_value = g_strconcat (*return_value, " ", mod, " (", s, ")", NULL);
                g_free (s);
        }
        return ptr;
@@ -508,7 +512,7 @@ dis_stringify_modifiers (MonoImage *m, int n, MonoCustomMod *mod)
                char *tok = dis_stringify_token (m, mod[i].token);
                if (i > 0)
                        g_string_sprintfa (s, " ");
-               g_string_sprintfa (s, "%s (%s)", mod[i].required ? "modreq": "modopt", tok);
+               g_string_sprintfa (s, " %s (%s)", mod[i].required ? "modreq": "modopt", tok);
                g_free (tok);
        }
        g_string_append_c (s, ' ');
@@ -791,6 +795,12 @@ get_generic_param (MonoImage *m, MonoGenericContainer *container)
 
                if (i > 0)
                        g_string_append (result, ",");
+               
+               flags = param->flags & GENERIC_PARAMETER_ATTRIBUTE_VARIANCE_MASK;
+               if ((flags & GENERIC_PARAMETER_ATTRIBUTE_COVARIANT) == GENERIC_PARAMETER_ATTRIBUTE_COVARIANT)
+                       g_string_append (result, "+ ");
+               if ((flags & GENERIC_PARAMETER_ATTRIBUTE_CONTRAVARIANT) == GENERIC_PARAMETER_ATTRIBUTE_CONTRAVARIANT)
+                       g_string_append (result, "- ");
 
                flags = param->flags & GENERIC_PARAMETER_ATTRIBUTE_SPECIAL_CONSTRAINTS_MASK;
                if ((flags & GENERIC_PARAMETER_ATTRIBUTE_REFERENCE_TYPE_CONSTRAINT) == GENERIC_PARAMETER_ATTRIBUTE_REFERENCE_TYPE_CONSTRAINT)
@@ -828,6 +838,13 @@ get_generic_param (MonoImage *m, MonoGenericContainer *container)
         return retval;
 }
 
+char*
+dis_stringify_method_signature (MonoImage *m, MonoMethodSignature *method, int methoddef_row,
+                               MonoGenericContainer *container, gboolean fully_qualified)
+{
+       return dis_stringify_method_signature_full (m, method, methoddef_row, container, fully_qualified, TRUE);
+}
+
 /* 
  * @m: metadata context
  * @method: MonoMethodSignature to dis-stringify
@@ -839,14 +856,14 @@ get_generic_param (MonoImage *m, MonoGenericContainer *container)
  * Returns: Allocated stringified method signature
  */
 char*
-dis_stringify_method_signature (MonoImage *m, MonoMethodSignature *method, int methoddef_row,
-                               MonoGenericContext *context, gboolean fully_qualified)
+dis_stringify_method_signature_full (MonoImage *m, MonoMethodSignature *method, int methoddef_row,
+                               MonoGenericContainer *container, gboolean fully_qualified, gboolean with_marshal_info)
 {
        guint32 cols [MONO_METHOD_SIZE];
        guint32 pcols [MONO_PARAM_SIZE];
        guint32 param_index = 0, next_param_index = 0;
        gboolean has_param_row;
-       const char *name = "", *method_name = "";
+       const char *method_name = "";
        int free_method = 0;
        char *retval, *esname;
        char *type = NULL;
@@ -854,7 +871,6 @@ dis_stringify_method_signature (MonoImage *m, MonoMethodSignature *method, int m
        char *gen_param = NULL;
        GString *result = g_string_new ("");
        GString *result_ret = g_string_new ("");
-       MonoGenericContainer *container = NULL;
        int i, start;
         
        g_assert (method || methoddef_row);
@@ -868,19 +884,14 @@ 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, context ? context->container : NULL);
-                       if (container) {
-                               mono_metadata_load_generic_param_constraints (
-                                       m, MONO_TOKEN_METHOD_DEF | methoddef_row, container);
-                               context = (MonoGenericContext *) container;
-                       }
+                       container = mono_metadata_load_generic_params (m, MONO_TOKEN_METHOD_DEF | methoddef_row, container);
+                       if (container)
+                               mono_metadata_load_generic_param_constraints (m, MONO_TOKEN_METHOD_DEF | methoddef_row, container);
 
                        mono_metadata_decode_blob_size (sig, &sig);
                        method = mono_metadata_parse_method_signature_full (m, container, methoddef_row, sig, &sig);
                        free_method = 1;
-               } else if (context)
-                       container = context->container;
+               }
 
                if (container && container->is_method)
                        gen_param = get_generic_param (m, container);
@@ -896,8 +907,8 @@ dis_stringify_method_signature (MonoImage *m, MonoMethodSignature *method, int m
        start = method->hasthis ? 0 : 1;
        for (i = 0; i < method->param_count + 1; ++i) {
                marshal_info = NULL;
-               name = "";
                has_param_row = param_index && param_index < next_param_index;
+               esname = NULL;
 
                if (method->param_count == 0 && !has_param_row)
                        /* method has zero parameters, and no row for return val in the PARAM table */
@@ -908,9 +919,10 @@ dis_stringify_method_signature (MonoImage *m, MonoMethodSignature *method, int m
                
                if (has_param_row && i == pcols [MONO_PARAM_SEQUENCE]) {
                        if (i)
-                               name = mono_metadata_string_heap (m, pcols [MONO_PARAM_NAME]);
+                               esname = get_escaped_name (
+                                               mono_metadata_string_heap (m, pcols [MONO_PARAM_NAME]));
 
-                       if (pcols [MONO_PARAM_FLAGS] & PARAM_ATTRIBUTE_HAS_FIELD_MARSHAL) {
+                       if (with_marshal_info && (pcols [MONO_PARAM_FLAGS] & PARAM_ATTRIBUTE_HAS_FIELD_MARSHAL)) {
                                const char *tp;
                                MonoMarshalSpec *spec;
                                tp = mono_metadata_get_marshal_info (m, param_index - 1, FALSE);
@@ -925,7 +937,8 @@ dis_stringify_method_signature (MonoImage *m, MonoMethodSignature *method, int m
                        param_index ++;
                } else {
                        if (i)
-                               name = g_strdup_printf ("A_%i", i - start);
+                               /* A_[0-9]* does not require escaping */
+                               esname = g_strdup_printf ("A_%i", i - start);
                }
 
                if (!i)
@@ -936,7 +949,6 @@ dis_stringify_method_signature (MonoImage *m, MonoMethodSignature *method, int m
 
                retval = dis_stringify_param (m, method->params [i - 1]);
 
-               esname = get_escaped_name (name);
                g_string_append_printf (result, "%s%s %s", retval, marshal_info ? marshal_info : "", esname);
                g_free (retval);
                g_free (esname);
@@ -955,6 +967,7 @@ dis_stringify_method_signature (MonoImage *m, MonoMethodSignature *method, int m
                char *estype = get_escaped_name (type);
                g_string_sprintfa (result_ret, "%s::", estype);
                g_free (estype);
+               g_free (type);
        }
        esname = get_escaped_name (method_name);
        g_string_append (result_ret, esname);
@@ -1017,6 +1030,10 @@ get_escaped_class_name (MonoClass *c)
 {
        char *result, *esname;
 
+       if (c->type_token == mono_metadata_make_token (MONO_TABLE_TYPEDEF, 1))
+               /* <Module> */
+               return NULL;
+
        if (c->rank || c->byval_arg.type == MONO_TYPE_PTR) 
                g_assert (0);
 
@@ -1044,6 +1061,10 @@ dis_stringify_object_with_class (MonoImage *m, MonoClass *c, gboolean prefix, gb
        const char *otype = type->type == MONO_TYPE_VALUETYPE ? "valuetype " : "class " ;
        char *assemblyref = NULL, *result, *esname, *generic = NULL;
        
+       if (c->type_token == mono_metadata_make_token (MONO_TABLE_TYPEDEF, 1))
+               /* <Module> */
+               return NULL;
+
        if (m != c->image) {
                if (c->image->assembly_name) {
                        /* we cheat */
@@ -1064,14 +1085,15 @@ dis_stringify_object_with_class (MonoImage *m, MonoClass *c, gboolean prefix, gb
 
        if (c->generic_class) {
                MonoGenericClass *gclass = c->generic_class;
+               MonoGenericInst *inst = gclass->context.class_inst;
                GString *str = g_string_new ("");
                int i;
 
-               for (i = 0; i < gclass->inst->type_argc; i++){
-                       char *t = dis_stringify_type (m, gclass->inst->type_argv [i], is_def);
+               for (i = 0; i < inst->type_argc; i++){
+                       char *t = dis_stringify_type (m, inst->type_argv [i], is_def);
 
                        g_string_append (str, t);
-                       if (i+1 != gclass->inst->type_argc)
+                       if (i+1 != inst->type_argc)
                                g_string_append (str, ", ");
                        g_free (t);
                }
@@ -1175,15 +1197,16 @@ dis_stringify_type (MonoImage *m, MonoType *type, gboolean is_def)
                break;
        case MONO_TYPE_GENERICINST: {
                GString *str = g_string_new ("");
+               MonoGenericInst *inst;
                int i;
                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], is_def);
+               inst = type->data.generic_class->context.class_inst;
+               for (i = 0; i < inst->type_argc; i++){
+                       char *t = dis_stringify_type (m, inst->type_argv [i], is_def);
 
                        g_string_append (str, t);
-                       if (i+1 != type->data.generic_class->inst->type_argc)
+                       if (i+1 != inst->type_argc)
                                g_string_append (str, ", ");
                        g_free (t);
                }
@@ -1201,8 +1224,12 @@ dis_stringify_type (MonoImage *m, MonoType *type, gboolean is_def)
 
        if (type->byref)
                byref = "&";
+       
+       if (!bare)
+               /* bare is NULL, for <Module> */
+               return bare;
                
-       result = g_strconcat (mods ? mods : "", bare, byref, pinned, NULL);
+       result = g_strconcat (bare, byref, pinned, mods ? mods : "", NULL);
 
        g_free (bare);
 
@@ -1221,7 +1248,7 @@ dis_stringify_type (MonoImage *m, MonoType *type, gboolean is_def)
  * Returns: the new ptr to continue decoding
  */
 const char *
-get_type (MonoImage *m, const char *ptr, char **result, gboolean is_def, MonoGenericContext *context)
+get_type (MonoImage *m, const char *ptr, char **result, gboolean is_def, MonoGenericContainer *container)
 {
        const char *start = ptr;
        guint32 type;
@@ -1252,7 +1279,7 @@ get_type (MonoImage *m, const char *ptr, char **result, gboolean is_def, MonoGen
                int count, i;
                char *temp;
 
-               ptr = get_type (m, ptr, &temp, is_def, context);
+               ptr = get_type (m, ptr, &temp, is_def, container);
                g_string_append (str, temp);
                g_free (temp);
 
@@ -1262,7 +1289,7 @@ get_type (MonoImage *m, const char *ptr, char **result, gboolean is_def, MonoGen
                for (i = 0; i < count; i++) {
                        if (i)
                                g_string_append (str, ",");
-                       ptr = get_type (m, ptr, &temp, is_def, context);
+                       ptr = get_type (m, ptr, &temp, is_def, container);
                        g_string_append (str, temp);
                }
 
@@ -1273,9 +1300,8 @@ get_type (MonoImage *m, const char *ptr, char **result, gboolean is_def, MonoGen
        }
 
        default:
-               t = mono_metadata_parse_type_full (m, context ? context->container : NULL, MONO_PARSE_TYPE, 0, start, &ptr);
+               t = mono_metadata_parse_type_full (m, container, MONO_PARSE_TYPE, 0, start, &ptr);
                *result = dis_stringify_type (m, t, is_def);
-               mono_metadata_free_type (t);
                break;
        }
 
@@ -1287,7 +1313,7 @@ get_type (MonoImage *m, const char *ptr, char **result, gboolean is_def, MonoGen
  * Returns a stringified representation of a FieldSig (22.2.4)
  */
 char *
-get_field_signature (MonoImage *m, guint32 blob_signature, MonoGenericContext *context)
+get_field_signature (MonoImage *m, guint32 blob_signature, MonoGenericContainer *container)
 {
        char *allocated_modifier_string, *allocated_type_string;
        const char *ptr = mono_metadata_blob_heap (m, blob_signature);
@@ -1303,12 +1329,12 @@ get_field_signature (MonoImage *m, guint32 blob_signature, MonoGenericContext *c
        ptr++; len--;
        
        ptr = get_custom_mod (m, ptr, &allocated_modifier_string);
-       ptr = get_type (m, ptr, &allocated_type_string, FALSE, context);
+       ptr = get_type (m, ptr, &allocated_type_string, FALSE, container);
 
        res = g_strdup_printf (
-               "%s %s",
-               allocated_modifier_string ? allocated_modifier_string : "",
-               allocated_type_string);
+               "%s%s",
+               allocated_type_string,
+               allocated_modifier_string ? allocated_modifier_string : "");
        
        if (allocated_modifier_string)
                g_free (allocated_modifier_string);
@@ -1363,7 +1389,7 @@ decode_literal (MonoImage *m, guint32 token)
  * Returns: the new ptr to continue decoding.
  */
 const char *
-get_ret_type (MonoImage *m, const char *ptr, char **ret_type, MonoGenericContext *context)
+get_ret_type (MonoImage *m, const char *ptr, char **ret_type, MonoGenericContainer *container)
 {
        GString *str = g_string_new ("");
        char *mod = NULL;
@@ -1371,11 +1397,6 @@ get_ret_type (MonoImage *m, const char *ptr, char **ret_type, MonoGenericContext
        int has_byref = 0;
        
        ptr = get_custom_mod (m, ptr, &mod);
-       if (mod){
-               g_string_append (str, mod);
-               g_string_append_c (str, ' ');
-               g_free (mod);
-       }
 
        if (*ptr == MONO_TYPE_TYPEDBYREF){
                g_string_append (str, "typedref");
@@ -1389,13 +1410,19 @@ get_ret_type (MonoImage *m, const char *ptr, char **ret_type, MonoGenericContext
                        ptr++;
                }
 
-               ptr = get_type (m, ptr, &allocated_type_string, FALSE, context);
+               ptr = get_type (m, ptr, &allocated_type_string, FALSE, container);
                g_string_append (str, allocated_type_string);
                if (has_byref)
                        g_string_append (str, "& ");
                g_free (allocated_type_string);
        }
 
+       if (mod){
+               g_string_append (str, mod);
+               g_string_append_c (str, ' ');
+               g_free (mod);
+       }
+
        *ret_type = str->str;
        g_string_free (str, FALSE);
 
@@ -1413,17 +1440,12 @@ get_ret_type (MonoImage *m, const char *ptr, char **ret_type, MonoGenericContext
  * Returns: the new ptr to continue decoding.
  */
 const char *
-get_param (MonoImage *m, const char *ptr, char **retval, MonoGenericContext *context)
+get_param (MonoImage *m, const char *ptr, char **retval, MonoGenericContainer *container)
 {
        GString *str = g_string_new ("");
        char *allocated_mod_string, *allocated_type_string;
        
        ptr = get_custom_mod (m, ptr, &allocated_mod_string);
-       if (allocated_mod_string){
-               g_string_append (str, allocated_mod_string);
-               g_string_append_c (str, ' ');
-               g_free (allocated_mod_string);
-       }
        
        if (*ptr == MONO_TYPE_TYPEDBYREF){
                g_string_append (str, " typedref ");
@@ -1435,13 +1457,19 @@ get_param (MonoImage *m, const char *ptr, char **retval, MonoGenericContext *con
                        ptr++;
                        by_ref = 1;
                }
-               ptr = get_type (m, ptr, &allocated_type_string, FALSE, context);
+               ptr = get_type (m, ptr, &allocated_type_string, FALSE, container);
                g_string_append (str, allocated_type_string);
                if (by_ref)
                        g_string_append_c (str, '&');
                g_free (allocated_type_string);
        }
 
+       if (allocated_mod_string){
+               g_string_append (str, allocated_mod_string);
+               g_string_append_c (str, ' ');
+               g_free (allocated_mod_string);
+       }
+
        *retval = str->str;
        g_string_free (str, FALSE);
        return ptr;
@@ -1489,6 +1517,9 @@ get_escaped_name (const char *name)
        const char *s;
        char *ret, *esc;
 
+       if (!name)
+               return NULL;
+
        g_assert (key_table);
 
        if (strlen (name) == 0)
@@ -1509,7 +1540,7 @@ get_escaped_name (const char *name)
 
        for (s = name; *s; s++) {
                if (isalnum (*s) || *s == '_' || *s == '$' || *s == '@' ||
-                   *s == '?' || *s == '.' || *s == 0 || *s == '!' || *s == '`')
+                   *s == '?' || (*s == '.' && s != name) || *s == 0 || *s == '!' || *s == '`')
                        continue;
 
                esc = str_escape (name, "'\\");
@@ -1669,10 +1700,10 @@ get_methodref_signature (MonoImage *m, guint32 blob_signature, const char *fancy
  * Returns a stringifed representation of a field ref
  */
 char *
-get_fieldref_signature (MonoImage *m, int idx, MonoGenericContext *context)
+get_fieldref_signature (MonoImage *m, int idx, MonoGenericContainer *container)
 {
        guint32 cols [MONO_MEMBERREF_SIZE];
-       MonoGenericContext *new_context;
+       MonoGenericContainer *new_container;
        char *type, *esname;
         char *sig;
        char *full_sig;
@@ -1680,13 +1711,17 @@ get_fieldref_signature (MonoImage *m, int idx, MonoGenericContext *context)
         mono_metadata_decode_row (&m->tables [MONO_TABLE_MEMBERREF],
                                  idx - 1, cols, MONO_MEMBERREF_SIZE);
 
-       new_context = get_memberref_context (m, cols [MONO_MEMBERREF_CLASS], context);
-        sig = get_field_signature (m, cols [MONO_MEMBERREF_SIGNATURE], new_context);
+       new_container = get_memberref_container (m, cols [MONO_MEMBERREF_CLASS], container);
+        sig = get_field_signature (m, cols [MONO_MEMBERREF_SIGNATURE], new_container);
 
-       type = get_memberref_parent (m, cols [MONO_MEMBERREF_CLASS], context);
+       type = get_memberref_parent (m, cols [MONO_MEMBERREF_CLASS], container);
        esname = get_escaped_name (mono_metadata_string_heap (m, cols [MONO_MEMBERREF_NAME]));
 
-        full_sig = g_strdup_printf ("%s %s::%s", sig, type, esname);
+       full_sig = g_strdup_printf ("%s %s%s%s", 
+                       sig, 
+                       type ? type : "", 
+                       type ? "::" : "",
+                       esname);
         g_free (sig);
        g_free (type);
        g_free (esname);
@@ -1704,7 +1739,7 @@ get_fieldref_signature (MonoImage *m, int idx, MonoGenericContext *context)
  * the TypeDef table and locate the actual "owner" of the field
  */
 char *
-get_field (MonoImage *m, guint32 token, MonoGenericContext *context)
+get_field (MonoImage *m, guint32 token, MonoGenericContainer *container)
 {
        int idx = mono_metadata_token_index (token);
        guint32 cols [MONO_FIELD_SIZE];
@@ -1716,12 +1751,12 @@ get_field (MonoImage *m, guint32 token, MonoGenericContext *context)
         * defined in another module/assembly, just like in get_method ()
         */
        if (mono_metadata_token_code (token) == MONO_TOKEN_MEMBER_REF) {
-                return get_fieldref_signature (m, idx, context);
+                return get_fieldref_signature (m, idx, container);
        }
        g_assert (mono_metadata_token_code (token) == MONO_TOKEN_FIELD_DEF);
 
        mono_metadata_decode_row (&m->tables [MONO_TABLE_FIELD], idx - 1, cols, MONO_FIELD_SIZE);
-       sig = get_field_signature (m, cols [MONO_FIELD_SIGNATURE], context);
+       sig = get_field_signature (m, cols [MONO_FIELD_SIGNATURE], container);
 
        /*
         * To locate the actual "container" for this field, we have to scan
@@ -1732,8 +1767,11 @@ get_field (MonoImage *m, guint32 token, MonoGenericContext *context)
        type = get_typedef (m, type_idx);
        estype = get_escaped_name (type);
        esname = get_escaped_name (mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]));
-       res = g_strdup_printf ("%s %s::%s",
-                       sig, estype, esname);
+       res = g_strdup_printf ("%s %s%s%s",
+                       sig, 
+                       estype ? estype : "",
+                       estype ? "::" : "",
+                       esname);
 
        g_free (type);
        g_free (sig);
@@ -1743,8 +1781,8 @@ get_field (MonoImage *m, guint32 token, MonoGenericContext *context)
        return res;
 }
 
-static MonoGenericContext *
-get_memberref_context (MonoImage *m, guint32 mrp_token, MonoGenericContext *context)
+static MonoGenericContainer *
+get_memberref_container (MonoImage *m, guint32 mrp_token, MonoGenericContainer *container)
 {
        MonoClass *klass;
 
@@ -1756,23 +1794,22 @@ 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, NULL);
+               return mono_metadata_load_generic_params (m, MONO_TOKEN_TYPE_DEF | idx, NULL);
                
        case 1: /* TypeRef */
                return NULL;
                
        case 4: /* TypeSpec */
-               klass = mono_class_get_full (m, MONO_TOKEN_TYPE_SPEC | idx, context);
+               klass = mono_class_get_full (m, MONO_TOKEN_TYPE_SPEC | idx, (MonoGenericContext *) container);
                g_assert (klass);
-               return klass->generic_class ? klass->generic_class->context : NULL;
+               return klass->generic_class ? klass->generic_class->container_class->generic_container : NULL;
        }
        g_assert_not_reached ();
        return NULL;
 }
 
 static char *
-get_memberref_parent (MonoImage *m, guint32 mrp_token, MonoGenericContext *context)
+get_memberref_parent (MonoImage *m, guint32 mrp_token, MonoGenericContainer *container)
 {
        /*
         * mrp_index is a MemberRefParent coded index
@@ -1794,7 +1831,7 @@ get_memberref_parent (MonoImage *m, guint32 mrp_token, MonoGenericContext *conte
                return g_strdup ("TODO:MethodDef");
                
        case 4: /* TypeSpec */
-               return get_typespec (m, idx, FALSE, context);
+               return get_typespec (m, idx, FALSE, container);
        }
        g_assert_not_reached ();
        return NULL;
@@ -1810,7 +1847,7 @@ get_memberref_parent (MonoImage *m, guint32 mrp_token, MonoGenericContext *conte
  * the TypeDef table and locate the actual "owner" of the field
  */
 static char *
-get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericContext *context)
+get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericContainer *container)
 {
        int idx = mono_metadata_token_index (token);
        guint32 member_cols [MONO_MEMBERREF_SIZE], method_cols [MONO_METHOD_SIZE];
@@ -1818,19 +1855,18 @@ get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericConte
        char *name;
 
        MonoMethod *mh;
-       MonoGenericContext *gc = context;
+       MonoGenericContainer *type_container = container;
 
-       mh = mono_get_method_full (m, token, NULL, context);
+       mh = mono_get_method_full (m, token, NULL, (MonoGenericContext *) container);
        if (mh) {
-               mh = mono_get_inflated_method (mh);
                if (mono_method_signature (mh)->is_inflated)
-                       context = ((MonoMethodInflated *) mh)->context;
+                       container = mono_method_get_generic_container (((MonoMethodInflated *) mh)->declaring);
                esname = get_escaped_name (mh->name);
                sig = dis_stringify_type (m, &mh->klass->byval_arg, TRUE);
                if (show_tokens)
-                       name = g_strdup_printf ("%s/*%08x*/::%s", sig, token, esname);
+                       name = g_strdup_printf ("%s/*%08x*/%s%s", sig ? sig : "", token, sig ? "::" : "", esname);
                else
-                       name = g_strdup_printf ("%s::%s", sig, esname);
+                       name = g_strdup_printf ("%s%s%s", sig ? sig : "", sig ? "::" : "", esname);
                g_free (sig);
                g_free (esname);
        } else
@@ -1847,18 +1883,22 @@ get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericConte
        case MONO_TOKEN_MEMBER_REF: {
                mono_metadata_decode_row (&m->tables [MONO_TABLE_MEMBERREF],
                                          idx - 1, member_cols, MONO_MEMBERREF_SIZE);
-               if (!name)
-                       name = g_strdup_printf ("%s::%s",
-                                               get_memberref_parent (m, member_cols [MONO_MEMBERREF_CLASS], context),
+               if (!name) {
+                       char *parent = get_memberref_parent (m, member_cols [MONO_MEMBERREF_CLASS], container);
+                       name = g_strdup_printf ("%s%s%s",
+                                               parent ? parent : "", 
+                                               parent ? "::" : "",
                                                mono_metadata_string_heap (m, member_cols [MONO_MEMBERREF_NAME]));
+                       g_free (parent);
+               }
                if (mh) {
                        int arity = 0;
 
-                       if (mh->generic_container)
-                               arity = mh->generic_container->type_argc;
+                       if (mh->is_generic)
+                               arity = mono_method_get_generic_container (mh)->type_argc;
                        else
-                       if (mh->is_inflated && ((MonoMethodInflated *)mh)->declaring->generic_container)
-                               arity = ((MonoMethodInflated*) mh)->declaring->generic_container->type_argc;
+                       if (mh->is_inflated && ((MonoMethodInflated *)mh)->declaring->is_generic)
+                               arity = mono_method_get_generic_container (((MonoMethodInflated*) mh)->declaring)->type_argc;
 
                        if (arity > 0) {
                                char *str = g_strdup_printf ("%s <[%d]>", name, arity);
@@ -1875,7 +1915,7 @@ get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericConte
                 mono_metadata_decode_row (&m->tables [MONO_TABLE_METHODSPEC],
                                 idx - 1, member_cols, MONO_METHODSPEC_SIZE);
                token = member_cols [MONO_METHODSPEC_METHOD];
-                sig = get_methodspec (m, idx, token, name, gc);
+                sig = get_methodspec (m, idx, token, name, type_container);
                break;
        }
 
@@ -1899,9 +1939,9 @@ get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericConte
 }
 
 char *
-get_method (MonoImage *m, guint32 token, MonoGenericContext *context)
+get_method (MonoImage *m, guint32 token, MonoGenericContainer *container)
 {
-       return get_method_core (m, token, TRUE, context);
+       return get_method_core (m, token, TRUE, container);
 }
 
 /**
@@ -1923,7 +1963,10 @@ get_methoddef (MonoImage *m, guint32 idx)
        mh = mono_get_method (m, MONO_TOKEN_METHOD_DEF | idx, NULL);
        if (mh) {
                sig = dis_stringify_type (m, &mh->klass->byval_arg, FALSE);
-               name = g_strdup_printf ("%s::%s", sig, mh->name);
+               name = g_strdup_printf ("%s%s%s", 
+                               sig ? sig : "",
+                               sig ? "::" : "",
+                               mh->name);
                g_free (sig);
        } else
                name = NULL;
@@ -1935,7 +1978,7 @@ get_methoddef (MonoImage *m, guint32 idx)
 }
 
 char *
-get_method_type_param (MonoImage *m, guint32 blob_signature, MonoGenericContext *context)
+get_method_type_param (MonoImage *m, guint32 blob_signature, MonoGenericContainer *container)
 {
        GString *res = g_string_new ("");
        const char *ptr = mono_metadata_blob_heap (m, blob_signature);
@@ -1952,7 +1995,7 @@ get_method_type_param (MonoImage *m, guint32 blob_signature, MonoGenericContext
        for (i = 0; i < param_count; i++){
                char *param = NULL;
 
-               ptr = get_param (m, ptr, &param, context);
+               ptr = get_param (m, ptr, &param, container);
                g_string_append (res, param);
                if (i+1 != param_count)
                        g_string_append (res, ", ");
@@ -1972,7 +2015,7 @@ get_method_type_param (MonoImage *m, guint32 blob_signature, MonoGenericContext
  */
 
 char *
-get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name, MonoGenericContext *context)
+get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name, MonoGenericContainer *type_container)
 {
         GString *res = g_string_new ("");
        guint32 member_cols [MONO_MEMBERREF_SIZE], method_cols [MONO_METHOD_SIZE];
@@ -1980,8 +2023,7 @@ get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name, Mo
         const char *ptr;
        guint32 sig = 0;
        int param_count, cconv, i, gen_count = 0;
-       MonoGenericContainer *container = NULL;
-       MonoGenericContext *parent_context = context;
+       MonoGenericContainer *container;
        MonoMethod *mh = NULL;
 
        switch (token & MONO_METHODDEFORREF_MASK) {
@@ -2004,10 +2046,11 @@ get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name, Mo
        ptr = mono_metadata_blob_heap (m, sig);
        mono_metadata_decode_value (ptr, &ptr);
        
-       mh = mono_get_method_full (m, method_dor_to_token (token), NULL, parent_context);
+       mh = mono_get_method_full (m, method_dor_to_token (token), NULL, (MonoGenericContext *) type_container);
        g_assert (mh);
-       if ((container = mh->generic_container))
-               context = (MonoGenericContext*) container;
+       container = mono_method_get_generic_container (mh);
+       if (!container)
+               container = type_container;
 
        if (*ptr & 0x20){
                if (*ptr & 0x40)
@@ -2025,7 +2068,7 @@ get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name, Mo
        param_count = mono_metadata_decode_value (ptr, &ptr);
        if (cconv != 0xa) {
                 char *allocated_ret_type;
-               ptr = get_ret_type (m, ptr, &allocated_ret_type, context);
+               ptr = get_ret_type (m, ptr, &allocated_ret_type, container);
                g_string_append (res, allocated_ret_type);
                g_free (allocated_ret_type);
        }
@@ -2038,7 +2081,7 @@ get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name, Mo
         mono_metadata_decode_row (&m->tables [MONO_TABLE_METHODSPEC],
                         idx - 1, member_cols, MONO_METHODSPEC_SIZE);
         token = member_cols [MONO_METHODSPEC_SIGNATURE];
-        type_param = get_method_type_param (m, token, parent_context);
+        type_param = get_method_type_param (m, token, type_container);
         g_string_append (res, type_param);
        g_string_append (res, " (");
 
@@ -2049,7 +2092,7 @@ get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name, Mo
        for (i = 0; i < param_count; i++){
                char *param = NULL;
                
-               ptr = get_param (m, ptr, &param, context);
+               ptr = get_param (m, ptr, &param, container);
                g_string_append (res, param);
                if (i+1 != param_count)
                        g_string_append (res, ", ");
@@ -2125,7 +2168,7 @@ get_encoded_user_string_bytearray (const unsigned char* ptr, int len)
 char*
 get_encoded_user_string_or_bytearray (const unsigned char *ptr, int len)
 {
-       unsigned char *res, *eres, *result;
+       char *res, *eres, *result;
        int i;
 
        res = g_malloc ((len >> 1) + 1);
@@ -2178,10 +2221,10 @@ stringify_double (double r)
 char *
 get_constant (MonoImage *m, MonoTypeEnum t, guint32 blob_index)
 {
-       const unsigned char *ptr = mono_metadata_blob_heap (m, blob_index);
+       const char *ptr = mono_metadata_blob_heap (m, blob_index);
        int len;
        
-       len = mono_metadata_decode_value (ptr, (const char**)&ptr);
+       len = mono_metadata_decode_value (ptr, &ptr);
        
        switch (t){
        case MONO_TYPE_BOOLEAN:
@@ -2192,7 +2235,7 @@ get_constant (MonoImage *m, MonoTypeEnum t, guint32 blob_index)
                
        case MONO_TYPE_U1:
        case MONO_TYPE_I1:
-               return g_strdup_printf ("int8(0x%02x)", (int) (*ptr));
+               return g_strdup_printf ("int8(0x%02x)", (int) ((*ptr) & 0xFF));
                break;
                
        case MONO_TYPE_U2:
@@ -2254,7 +2297,7 @@ get_constant (MonoImage *m, MonoTypeEnum t, guint32 blob_index)
                }
        }
        case MONO_TYPE_STRING:
-               return get_encoded_user_string_or_bytearray (ptr, len);
+               return get_encoded_user_string_or_bytearray ((const guchar*)ptr, len);
                
        case MONO_TYPE_CLASS:
                return g_strdup ("nullref");
@@ -2276,17 +2319,22 @@ get_constant (MonoImage *m, MonoTypeEnum t, guint32 blob_index)
  * constant.
  */
 char *
-get_token (MonoImage *m, guint32 token, MonoGenericContext *context)
+get_token (MonoImage *m, guint32 token, MonoGenericContainer *container)
 {
        char *temp, *result;
        guint32 idx = mono_metadata_token_index (token);
 
        switch (mono_metadata_token_code (token)){
        case MONO_TOKEN_FIELD_DEF:
-               temp = get_field (m, token, context);
+               temp = get_field (m, token, container);
                result = g_strdup_printf ("field %s", temp);
                g_free (temp);
                return result;
+       case MONO_TOKEN_METHOD_DEF:
+               temp = get_method (m, token, container);
+               result = g_strdup_printf ("method %s", temp);
+               g_free (temp);
+               return result;
        case MONO_TOKEN_TYPE_DEF:
                temp = get_typedef (m, idx);
                result = get_escaped_name (temp);
@@ -2295,7 +2343,7 @@ get_token (MonoImage *m, guint32 token, MonoGenericContext *context)
        case MONO_TOKEN_TYPE_REF:
                return get_typeref (m, idx);
        case MONO_TOKEN_TYPE_SPEC:
-               return get_typespec (m, idx, TRUE, context);
+               return get_typespec (m, idx, TRUE, container);
        case MONO_TOKEN_MEMBER_REF: {
                guint32 cols [MONO_MEMBERREF_SIZE];
                const char *sig;
@@ -2303,12 +2351,12 @@ get_token (MonoImage *m, guint32 token, MonoGenericContext *context)
                sig = mono_metadata_blob_heap (m, cols [MONO_MEMBERREF_SIGNATURE]);
                mono_metadata_decode_blob_size (sig, &sig);
                if (*sig == 0x6) { /* it's a field */
-                       temp = get_field (m, token, context);
+                       temp = get_field (m, token, container);
                        result = g_strdup_printf ("field %s", temp);
                        g_free (temp);
                        return result;
                } else {
-                       temp = get_method (m, token, context);
+                       temp = get_method (m, token, container);
                        result = g_strdup_printf ("method %s", temp);
                        g_free (temp);
                        return result;
@@ -2333,7 +2381,7 @@ get_token (MonoImage *m, guint32 token, MonoGenericContext *context)
  * at (token & 0xffffff) 
  */
 char *
-get_token_type (MonoImage *m, guint32 token, MonoGenericContext *context)
+get_token_type (MonoImage *m, guint32 token, MonoGenericContainer *container)
 {
        char *temp = NULL, *s = NULL;
        int idx;
@@ -2352,7 +2400,7 @@ get_token_type (MonoImage *m, guint32 token, MonoGenericContext *context)
                break;
                
        case MONO_TOKEN_TYPE_SPEC:
-               s = get_typespec (m, idx, FALSE, context);
+               s = get_typespec (m, idx, FALSE, container);
                break;
 
        default:
@@ -2372,7 +2420,7 @@ get_guid (MonoImage *m, guint32 guid_index)
        const unsigned char *guid;
        char *result;
 
-       guid = mono_metadata_guid_heap (m, guid_index);
+       guid = (const guchar*)mono_metadata_guid_heap (m, guid_index);
 
        result = g_strdup_printf ("{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}", 
                        guid [3], guid [2], guid [1], guid [0], guid [5], guid [4], guid [7], guid [6],
@@ -2935,6 +2983,7 @@ init_key_table (void)
        g_hash_table_insert (key_table, (char *) "sub", GINT_TO_POINTER (TRUE));
        g_hash_table_insert (key_table, (char *) "sub.ovf", GINT_TO_POINTER (TRUE));
        g_hash_table_insert (key_table, (char *) "sub.ovf.un", GINT_TO_POINTER (TRUE));
+       g_hash_table_insert (key_table, (char *) "switch", GINT_TO_POINTER (TRUE));
        g_hash_table_insert (key_table, (char *) "synchronized", GINT_TO_POINTER (TRUE));
        g_hash_table_insert (key_table, (char *) "syschar", GINT_TO_POINTER (TRUE));
        g_hash_table_insert (key_table, (char *) "sysstring", GINT_TO_POINTER (TRUE));
@@ -2981,7 +3030,7 @@ method_dor_to_token (guint32 idx) {
 }
 
 char *
-get_method_override (MonoImage *m, guint32 token, MonoGenericContext *context)
+get_method_override (MonoImage *m, guint32 token, MonoGenericContainer *container)
 {
        MonoTableInfo *t = &m->tables [MONO_TABLE_METHODIMPL];
        int i;
@@ -2997,19 +3046,18 @@ get_method_override (MonoImage *m, guint32 token, MonoGenericContext *context)
 
                if (token == impl) {
                        MonoMethod *mh = NULL;
-                       mh = mono_get_method_full (m, decl, NULL, context);
-                       mh = mono_get_inflated_method (mh);
+                       mh = mono_get_method_full (m, decl, NULL, (MonoGenericContext *) container);
 
                        if (mh && (mh->klass && (mh->klass->generic_class || mh->klass->generic_container))) {
                                char *meth_str;
                                char *ret;
                                
-                               meth_str = get_method_core (m, decl, TRUE, context);
+                               meth_str = get_method_core (m, decl, TRUE, container);
                                ret = g_strdup_printf ("method %s", meth_str);
                                g_free (meth_str);
                                return ret;
                        } else {
-                               return get_method_core (m, decl, FALSE, context);
+                               return get_method_core (m, decl, FALSE, container);
                        }
                }
        }