Merge pull request #4048 from kumpera/iface_casting_cleanup
[mono.git] / mono / dis / dis-cil.c
old mode 100644 (file)
new mode 100755 (executable)
index 2a77cf8..bc40414
 #include "get.h"
 #include "dump.h"
 #include "dis-cil.h"
+#include "util.h"
 #include "mono/metadata/opcodes.h"
+#include "mono/metadata/class-internals.h"
 #include "mono/utils/mono-compiler.h"
 
-#ifndef HAVE_ISINF
-
-#ifdef HAVE_IEEEFP_H
-#include <ieeefp.h>
-int isinf (double);
-int
-isinf (double num)
-{
-       fpclass_t klass;
-
-       klass = fpclass (num);
-       if (klass == FP_NINF)
-               return -1;
-
-       if (klass == FP_PINF)
-               return 1;
-
-       return 0;
-}
-#else
-#error "Don't know how to implement isinf for this platform."
-#endif
-
-#endif
-
-/*
- * Strings on the US heap are encoded using UTF-16.  Poor man's
- * UTF-16 to UTF-8.  I know its broken, use libunicode later.
- */
-static char *
-get_encoded_user_string (const char *ptr)
-{
-       char *res, *result;
-       int len, i, j;
-
-       len = mono_metadata_decode_blob_size (ptr, &ptr);
-       res = g_malloc (len + 1);
-
-       /*
-        * I should really use some kind of libunicode here
-        */
-       for (i = 0, j = 0; i < len; j++, i += 2)
-               res [j] = ptr [i];
-
-       res [j] = 0;
-
-       result = g_strescape (res, NULL);
-       g_free (res);
-       
-       return result;
-}
-
 #define CODE_INDENT g_assert (indent_level < 512); \
        indent[indent_level*2] = ' ';   \
        indent[indent_level*2+1] = ' '; \
@@ -82,7 +32,7 @@ get_encoded_user_string (const char *ptr)
        indent[indent_level*2] = 0;
 
 void
-dissasemble_cil (MonoImage *m, MonoMethodHeader *mh, MonoGenericContext *context)
+disassemble_cil (MonoImage *m, MonoMethodHeader *mh, MonoGenericContainer *container)
 {
        const unsigned char *start = mh->code;
        int size = mh->code_size;
@@ -90,7 +40,7 @@ dissasemble_cil (MonoImage *m, MonoMethodHeader *mh, MonoGenericContext *context
        const unsigned char *ptr = start;
        const MonoOpcode *entry;
        char indent[1024];
-       int i, indent_level = 0;
+       int i, j, indent_level = 0;
        gboolean in_fault = 0;
        const char *clause_names[] = {"catch", "filter", "finally", "", "fault"};
        gboolean *trys = NULL;
@@ -106,14 +56,19 @@ dissasemble_cil (MonoImage *m, MonoMethodHeader *mh, MonoGenericContext *context
 #endif
 
        if (mh->num_clauses) {
-              trys = g_malloc0 (sizeof (gboolean) * mh->num_clauses);
+              trys = (gboolean *)g_malloc0 (sizeof (gboolean) * mh->num_clauses);
               trys [0] = 1;
               for (i=1; i < mh->num_clauses; ++i) {
-#define pcl mh->clauses [i-1]  
+#define jcl mh->clauses [j]    
 #define cl mh->clauses [i]     
-                      if (pcl.try_offset != cl.try_offset || pcl.try_len != cl.try_len)
-                              trys [i] = 1;
-#undef pcl
+                      trys [i] = 1;
+                      for (j = 0; j < i; j++) {
+                              if (cl.try_offset == jcl.try_offset && cl.try_len == jcl.try_len) {
+                                      trys [i] = 0;
+                                      break;
+                              }
+                      }
+#undef jcl
 #undef cl
               }
        }
@@ -132,7 +87,7 @@ dissasemble_cil (MonoImage *m, MonoMethodHeader *mh, MonoGenericContext *context
                                 } else {
                                         char * klass = mh->clauses[i].flags ? g_strdup ("") :
                                                dis_stringify_object_with_class (m, mh->clauses[i].data.catch_class,
-                                                                                FALSE, FALSE);
+                                                                                TRUE, FALSE);
                                         fprintf (output, "\t%s%s %s { // %d\n", indent,
                                                         clause_names [mh->clauses[i].flags], klass, i);
                                         g_free (klass);
@@ -171,7 +126,7 @@ dissasemble_cil (MonoImage *m, MonoMethodHeader *mh, MonoGenericContext *context
                        guint32 token = read32 (ptr);
                        char *s;
                        
-                       s = get_field (m, token, context);
+                       s = get_field (m, token, container);
                        fprintf (output, "%s", s);
                        g_free (s);
                        ptr += 4;
@@ -198,7 +153,7 @@ dissasemble_cil (MonoImage *m, MonoMethodHeader *mh, MonoGenericContext *context
                        guint32 token = read32 (ptr);
                        char *s;
 
-                       s = get_method (m, token, context);
+                       s = get_method (m, token, container);
                        fprintf (output, "%s", s);
                        g_free (s);
                        ptr += 4;
@@ -212,15 +167,18 @@ dissasemble_cil (MonoImage *m, MonoMethodHeader *mh, MonoGenericContext *context
                        double r;
                        int inf;
                        readr8 (ptr, &r);
-                       inf = isinf (r);
+                       inf = dis_isinf (r);
                        if (inf == -1) 
                                fprintf (output, "(00 00 00 00 00 00 f0 ff)"); /* negative infinity */
                        else if (inf == 1)
                                fprintf (output, "(00 00 00 00 00 00 f0 7f)"); /* positive infinity */
-                       else if (isnan (r))
+                       else if (dis_isnan (r))
                                fprintf (output, "(00 00 00 00 00 00 f8 ff)"); /* NaN */
-                       else
-                               fprintf (output, "%g", r);
+                       else {
+                               char *str = stringify_double (r);
+                               fprintf (output, "%s", str);
+                               g_free (str);
+                       }
                        ptr += 8;
                        break;
                }
@@ -234,14 +192,15 @@ dissasemble_cil (MonoImage *m, MonoMethodHeader *mh, MonoGenericContext *context
                
                case MonoInlineString: {
                        guint32 token = read32 (ptr);
-                       
-                       char *s = get_encoded_user_string (
-                               mono_metadata_user_string (m, token & 0xffffff));
+                       const char *us_ptr = mono_metadata_user_string (m, token & 0xffffff);
+                       int len = mono_metadata_decode_blob_size (us_ptr, (const char**)&us_ptr);
+
+                       char *s = get_encoded_user_string_or_bytearray ((const guchar*)us_ptr, len);
                        
                        /*
                         * See section 23.1.4 on the encoding of the #US heap
                         */
-                       fprintf (output, "\"%s\"", s);
+                       fprintf (output, "%s", s);
                        g_free (s);
                        ptr += 4;
                        break;
@@ -270,7 +229,7 @@ dissasemble_cil (MonoImage *m, MonoMethodHeader *mh, MonoGenericContext *context
                        guint32 token = read32 (ptr);
                        char *s;
                        
-                       s = get_token (m, token, context);
+                       s = get_token (m, token, container);
                        fprintf (output, "%s", s);
                        g_free (s);
                        
@@ -280,7 +239,7 @@ dissasemble_cil (MonoImage *m, MonoMethodHeader *mh, MonoGenericContext *context
                
                case MonoInlineType: {
                        guint32 token = read32 (ptr);
-                       char *s = get_token_type (m, token, context);
+                       char *s = get_token_type (m, token, container);
                        fprintf (output, "%s", s);
                        g_free (s);
                        ptr += 4;
@@ -317,15 +276,18 @@ dissasemble_cil (MonoImage *m, MonoMethodHeader *mh, MonoGenericContext *context
                        
                        readr4 (ptr, &f);
 
-                       inf = isinf (f);
+                       inf = dis_isinf (f);
                        if (inf == -1) 
                                fprintf (output, "(00 00 80 ff)"); /* negative infinity */
                        else if (inf == 1)
                                fprintf (output, "(00 00 80 7f)"); /* positive infinity */
-                       else if (isnan (f))
+                       else if (dis_isnan (f))
                                fprintf (output, "(00 00 c0 ff)"); /* NaN */
-                       else
-                               fprintf (output, "%g", (double) f);
+                       else {
+                               char *str = stringify_double ((double) f);
+                               fprintf (output, "%s", str);
+                               g_free (str);
+                       }
                        ptr += 4;
                        break;
                }