2009-08-12 Mark Probst <mark.probst@gmail.com>
[mono.git] / mono / metadata / debug-helpers.c
index 3d2282baad84853a943396a03a784b24b7a0d474..5f6d509290fabdaf29c4ad1ee0bd64bef282fe3d 100644 (file)
@@ -1,7 +1,16 @@
+/*
+ * console-io.c: ConsoleDriver internal calls
+ *
+ * Author:
+ *     Mono Project (http://www.mono-project.com)
+ *
+ * Copyright (C) 2005-2008 Novell, Inc. (http://www.novell.com)
+ */
 
 #include <string.h>
 #include "mono/metadata/tokentype.h"
 #include "mono/metadata/opcodes.h"
+#include "mono/metadata/metadata-internals.h"
 #include "mono/metadata/class-internals.h"
 #include "mono/metadata/mono-endian.h"
 #include "mono/metadata/debug-helpers.h"
@@ -14,7 +23,7 @@ struct MonoMethodDesc {
        char *name;
        char *args;
        guint num_args;
-       gboolean include_namespace;
+       gboolean include_namespace, klass_glob, name_glob;
 };
 
 #ifdef HAVE_ARRAY_ELEM_INIT
@@ -162,7 +171,15 @@ mono_type_get_desc (GString *res, MonoType *type, gboolean include_namespace)
        }
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
-               g_string_append (res, type->data.generic_param->name);
+               if (type->data.generic_param) {
+                       MonoGenericParamInfo *info = mono_generic_param_info (type->data.generic_param);
+                       if (info)
+                               g_string_append (res, info->name);
+                       else
+                               g_string_append_printf (res, "%s%d", type->type == MONO_TYPE_VAR ? "!" : "!!", mono_generic_param_num (type->data.generic_param));
+               } else {
+                       g_string_append (res, "<unknown>");
+               }
                break;
        default:
                break;
@@ -249,6 +266,8 @@ mono_context_get_desc (MonoGenericContext *context)
  *
  * in all the loaded assemblies.
  *
+ * Both classname and methodname can contain '*' which matches anything.
+ *
  * Returns: a parsed representation of the method description.
  */
 MonoMethodDesc*
@@ -292,6 +311,10 @@ mono_method_desc_new (const char *name, gboolean include_namespace)
        result->klass = class_name;
        result->namespace = use_namespace? class_nspace: NULL;
        result->args = use_args? use_args: NULL;
+       if (strstr (result->name, "*"))
+               result->name_glob = TRUE;
+       if (strstr (result->klass, "*"))
+               result->klass_glob = TRUE;
        if (use_args) {
                end = use_args;
                if (*end)
@@ -343,7 +366,14 @@ gboolean
 mono_method_desc_match (MonoMethodDesc *desc, MonoMethod *method)
 {
        char *sig;
-       if (strcmp (desc->name, method->name))
+       gboolean name_match;
+
+       name_match = strcmp (desc->name, method->name) == 0;
+#ifndef _EGLIB_MAJOR
+       if (!name_match && desc->name_glob)
+               name_match = g_pattern_match_simple (desc->name, method->name);
+#endif
+       if (!name_match)
                return FALSE;
        if (!desc->args)
                return TRUE;
@@ -379,6 +409,12 @@ match_class (MonoMethodDesc *desc, int pos, MonoClass *klass)
 {
        const char *p;
 
+       if (desc->klass_glob && !strcmp (desc->klass, "*"))
+               return TRUE;
+#ifndef _EGLIB_MAJOR
+       if (desc->klass_glob && g_pattern_match_simple (desc->klass, klass->name))
+               return TRUE;
+#endif
        p = my_strrchr (desc->klass, '/', &pos);
        if (!p) {
                if (strncmp (desc->klass, klass->name, pos))
@@ -491,10 +527,38 @@ dis_one (GString *str, MonoDisHelper *dh, MonoMethod *method, const unsigned cha
                }
                ip += 4;
                break;
-       case MonoInlineString:
-               /* TODO */
+       case MonoInlineString: {
+               const char *blob;
+               char *s;
+               size_t len2;
+
+               if (!method->klass->image->dynamic) {
+                       token = read32 (ip);
+                       blob = mono_metadata_user_string (method->klass->image, mono_metadata_token_index (token));
+
+                       len2 = mono_metadata_decode_blob_size (blob, &blob);
+                       len2 >>= 1;
+
+#if G_BYTE_ORDER != G_LITTLE_ENDIAN
+                       {
+                               guint16 *buf = g_new (guint16, len2);
+                               int i;
+
+                               for (i = 0; i < len2; ++i)
+                                       buf [i] = GUINT16_FROM_LE (((guint16*)blob) [i]);
+                               s = g_utf16_to_utf8 (buf, len2, NULL, NULL, NULL);
+                               g_free (buf);
+                       }
+#else
+                               s = g_utf16_to_utf8 ((gunichar2*)blob, len2, NULL, NULL, NULL);
+#endif
+
+                       g_string_sprintfa (str, "\"%s\"", s);
+                       g_free (s);
+               }
                ip += 4;
                break;
+       }
        case MonoInlineVar:
                g_string_sprintfa (str, "%d", read16 (ip));
                ip += 2;
@@ -624,7 +688,7 @@ mono_field_full_name (MonoClassField *field)
        const char *nspace = field->parent->name_space;
 
        res = g_strdup_printf ("%s%s%s:%s", nspace, *nspace ? "." : "",
-                                                  field->parent->name, field->name);
+                                                  field->parent->name, mono_field_get_name (field));
 
        return res;
 }
@@ -643,10 +707,25 @@ mono_method_full_name (MonoMethod *method, gboolean signature)
                ginst_get_desc (str, ((MonoMethodInflated*)method)->context.method_inst);
                g_string_append (str, ">");
 
+               inst_desc = str->str;
+               g_string_free (str, FALSE);
+       } else if (method->is_generic) {
+               MonoGenericContainer *container = mono_method_get_generic_container (method);
+
+               GString *str = g_string_new ("");
+               g_string_append (str, "<");
+               ginst_get_desc (str, container->context.method_inst);
+               g_string_append (str, ">");
+
                inst_desc = str->str;
                g_string_free (str, FALSE);
        }
 
+       if (method->wrapper_type != MONO_WRAPPER_NONE)
+               sprintf (wrapper, "(wrapper %s) ", wrapper_type_to_str (method->wrapper_type));
+       else
+               strcpy (wrapper, "");
+
        if (signature) {
                char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
 
@@ -658,8 +737,7 @@ mono_method_full_name (MonoMethod *method, gboolean signature)
                                                           method->name, inst_desc ? inst_desc : "", tmpsig);
                g_free (tmpsig);
        } else {
-
-               res = g_strdup_printf ("%02d %s:%s%s", method->wrapper_type, klass_desc,
+               res = g_strdup_printf ("%s%s:%s%s", wrapper, klass_desc,
                                                           method->name, inst_desc ? inst_desc : "");
        }
 
@@ -727,7 +805,7 @@ static void
 print_field_value (const char *field_ptr, MonoClassField *field, int type_offset)
 {
        MonoType *type;
-       g_print ("At %p (ofs: %2d) %s: ", field_ptr, field->offset + type_offset, field->name);
+       g_print ("At %p (ofs: %2d) %s: ", field_ptr, field->offset + type_offset, mono_field_get_name (field));
        type = mono_type_get_underlying_type (field->type);
 
        switch (type->type) {