[runtime] Fix potential overflow when using mono_msec_ticks
[mono.git] / mono / metadata / opcodes.c
1 /*
2  * opcodes.c: CIL instruction information
3  *
4  * Author:
5  *   Paolo Molaro (lupus@ximian.com)
6  *
7  * Copyright 2002-2003 Ximian, Inc (http://www.ximian.com)
8  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
9  */
10 #include <mono/metadata/opcodes.h>
11 #include <stddef.h> /* for NULL */
12 #include <config.h>
13
14 #define MONO_PREFIX1_OFFSET MONO_CEE_ARGLIST
15 #define MONO_CUSTOM_PREFIX_OFFSET MONO_CEE_MONO_ICALL
16
17 #define OPDEF(a,b,c,d,e,f,g,h,i,j) \
18         { Mono ## e, MONO_FLOW_ ## j, MONO_ ## a },
19
20 const MonoOpcode
21 mono_opcodes [MONO_CEE_LAST + 1] = {
22 #include "mono/cil/opcode.def"
23         {0}
24 };
25
26 #undef OPDEF
27
28 #ifdef HAVE_ARRAY_ELEM_INIT
29 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
30 #define MSGSTRFIELD1(line) str##line
31 static const struct msgstr_t {
32 #define OPDEF(a,b,c,d,e,f,g,h,i,j) char MSGSTRFIELD(__LINE__) [sizeof (b)];
33 #include "mono/cil/opcode.def"
34 #undef OPDEF
35 } opstr = {
36 #define OPDEF(a,b,c,d,e,f,g,h,i,j) b,
37 #include "mono/cil/opcode.def"
38 #undef OPDEF
39 };
40 static const int16_t opidx [] = {
41 #define OPDEF(a,b,c,d,e,f,g,h,i,j) [MONO_ ## a] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
42 #include "mono/cil/opcode.def"
43 #undef OPDEF
44 };
45
46 const char*
47 mono_opcode_name (int opcode)
48 {
49         return (const char*)&opstr + opidx [opcode];
50 }
51
52 #else
53 #define OPDEF(a,b,c,d,e,f,g,h,i,j) b,
54 static const char* const
55 mono_opcode_names [MONO_CEE_LAST + 1] = {
56 #include "mono/cil/opcode.def"
57         NULL
58 };
59
60 const char*
61 mono_opcode_name (int opcode)
62 {
63         return mono_opcode_names [opcode];
64 }
65
66 #endif
67
68 MonoOpcodeEnum
69 mono_opcode_value (const mono_byte **ip, const mono_byte *end)
70 {
71         MonoOpcodeEnum res;
72         const mono_byte *p = *ip;
73
74         if (p >= end)
75                 return (MonoOpcodeEnum)-1;
76         if (*p == 0xfe) {
77                 ++p;
78                 if (p >= end)
79                         return (MonoOpcodeEnum)-1;
80                 res = (MonoOpcodeEnum)(*p + MONO_PREFIX1_OFFSET);
81         } else if (*p == MONO_CUSTOM_PREFIX) {
82                 ++p;
83                 if (p >= end)
84                         return (MonoOpcodeEnum)-1;
85                 res = (MonoOpcodeEnum)(*p + MONO_CUSTOM_PREFIX_OFFSET);
86         } else {
87                 res = (MonoOpcodeEnum)*p;
88         }
89         *ip = p;
90         return res;
91 }
92