Merge pull request #4621 from alexanderkyte/strdup_env
[mono.git] / mono / mini / interp / mintops.c
1 /**
2  * \file
3  * Utilities for handling interpreter VM instructions
4  *
5  * Authors:
6  *   Bernie Solomon (bernard@ugsolutions.com)
7  *
8  */
9 #include <glib.h>
10 #include <stdio.h>
11 #include "mintops.h"
12
13 #define OPDEF(a,b,c,d) \
14         b,
15 const char *mono_interp_opname[] = {
16 #include "mintops.def"
17         ""
18 };
19 #undef OPDEF
20
21 #define OPDEF(a,b,c,d) \
22         c,
23 unsigned char mono_interp_oplen[] = {
24 #include "mintops.def"
25         0
26 };
27 #undef OPDEF
28
29
30 #define OPDEF(a,b,c,d) \
31         d,
32 MintOpArgType mono_interp_opargtype[] = {
33 #include "mintops.def"
34         0
35 };
36 #undef OPDEF
37
38 const guint16 *
39 mono_interp_dis_mintop(const guint16 *base, const guint16 *ip)
40 {
41         int len = mono_interp_oplen [*ip];
42         guint32 token;
43         int target;
44         if (len < 0 || len > 10) {
45                 g_print ("op %d len %d\n", *ip, len);
46                 g_assert_not_reached ();
47         } else if (len == 0) { /* SWITCH */
48                 int n = READ32 (ip + 1);
49                 len = 3 + n * 2;
50         }
51
52         g_print ("IL_%04x: %-10s", ip - base, mono_interp_opname [*ip]);
53         switch (mono_interp_opargtype [*ip]) {
54         case MintOpNoArgs:
55                 break;
56         case MintOpUShortInt:
57                 g_print (" %u", * (guint16 *)(ip + 1));
58                 break;
59         case MintOpTwoShorts:
60                 g_print (" %u,%u", * (guint16 *)(ip + 1), * (guint16 *)(ip + 2));
61                 break;
62         case MintOpShortAndInt:
63                 g_print (" %u,%u", * (guint16 *)(ip + 1), (guint32)READ32(ip + 2));
64                 break;
65         case MintOpShortInt:
66                 g_print (" %d", * (short *)(ip + 1));
67                 break;
68         case MintOpClassToken:
69         case MintOpMethodToken:
70         case MintOpFieldToken:
71                 token = * (guint16 *)(ip + 1);
72                 g_print (" %u", token);
73                 break;
74         case MintOpInt:
75                 g_print (" %d", (gint32)READ32 (ip + 1));
76                 break;
77         case MintOpLongInt:
78                 g_print (" %lld", (gint64)READ64 (ip + 1));
79                 break;
80         case MintOpFloat: {
81                 gint32 tmp = READ32 (ip + 1);
82                 g_print (" %g", * (float *)&tmp);
83                 break;
84         }
85         case MintOpDouble: {
86                 gint64 tmp = READ64 (ip + 1);
87                 g_print (" %g", * (double *)&tmp);
88                 break;
89         }
90         case MintOpShortBranch:
91                 target = ip + * (short *)(ip + 1) - base;
92                 g_print (" IL_%04x", target);
93                 break;
94         case MintOpBranch:
95                 target = ip + (gint32)READ32 (ip + 1) - base;
96                 g_print (" IL_%04x", target);
97                 break;
98         case MintOpSwitch: {
99                 const guint16 *p = ip + 1;
100                 int sval = (gint32)READ32 (p);
101                 int i;
102                 p += 2;
103                 g_print ("(");
104                 for (i = 0; i < sval; ++i) {
105                         int offset;
106                         if (i > 0)
107                                 g_print (", ");
108                         offset = (gint32)READ32 (p);
109                         g_print ("IL_%04x", ip - base + 3 + 2 * sval + offset);
110                         p += 2;
111                 }
112                 g_print (")");
113                 break;
114         }
115         default:
116                 g_print("unknown arg type\n");
117         }
118
119         return ip + len;
120 }
121