New test.
[mono.git] / mono / metadata / opcodes.c
index cbf00514f8d613035a9925fef6f348d1f030f939..f8b430234727715fce4e60022f9aa18f24cffd21 100644 (file)
@@ -8,9 +8,10 @@
  */
 #include <mono/metadata/opcodes.h>
 #include <stddef.h> /* for NULL */
+#include <config.h>
 
 #define MONO_PREFIX1_OFFSET MONO_CEE_ARGLIST
-#define MONO_CUSTOM_PREFIX_OFFSET MONO_CEE_MONO_FUNC1
+#define MONO_CUSTOM_PREFIX_OFFSET MONO_CEE_MONO_ICALL
 
 #define OPDEF(a,b,c,d,e,f,g,h,i,j) \
        { Mono ## e, MONO_FLOW_ ## j, MONO_ ## a },
@@ -23,29 +24,68 @@ mono_opcodes [MONO_CEE_LAST + 1] = {
 
 #undef OPDEF
 
+#ifdef HAVE_ARRAY_ELEM_INIT
+#define MSGSTRFIELD(line) MSGSTRFIELD1(line)
+#define MSGSTRFIELD1(line) str##line
+static const struct msgstr_t {
+#define OPDEF(a,b,c,d,e,f,g,h,i,j) char MSGSTRFIELD(__LINE__) [sizeof (b)];
+#include "mono/cil/opcode.def"
+#undef OPDEF
+} opstr = {
 #define OPDEF(a,b,c,d,e,f,g,h,i,j) b,
+#include "mono/cil/opcode.def"
+#undef OPDEF
+};
+static const gint16 opidx [] = {
+#define OPDEF(a,b,c,d,e,f,g,h,i,j) [MONO_ ## a] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
+#include "mono/cil/opcode.def"
+#undef OPDEF
+};
 
-const char* const
+const char*
+mono_opcode_name (int opcode)
+{
+       return (const char*)&opstr + opidx [opcode];
+}
+
+#else
+#define OPDEF(a,b,c,d,e,f,g,h,i,j) b,
+static const char* const
 mono_opcode_names [MONO_CEE_LAST + 1] = {
 #include "mono/cil/opcode.def"
        NULL
 };
 
+const char*
+mono_opcode_name (int opcode)
+{
+       return mono_opcode_names [opcode];
+}
+
+#endif
+
 MonoOpcodeEnum
-mono_opcode_value (const guint8 **ip)
+mono_opcode_value (const guint8 **ip, const guint8 *end)
 {
        MonoOpcodeEnum res;
+       const guint8 *p = *ip;
 
-       if (**ip == 0xfe) {
-               ++*ip;
-               res = **ip + MONO_PREFIX1_OFFSET;
-       } else if (**ip == MONO_CUSTOM_PREFIX) {
-               ++*ip;
-               res = **ip + MONO_CUSTOM_PREFIX_OFFSET;
+       if (p >= end)
+               return -1;
+       if (*p == 0xfe) {
+               ++p;
+               if (p >= end)
+                       return -1;
+               res = *p + MONO_PREFIX1_OFFSET;
+       } else if (*p == MONO_CUSTOM_PREFIX) {
+               ++p;
+               if (p >= end)
+                       return -1;
+               res = *p + MONO_CUSTOM_PREFIX_OFFSET;
        } else {
-               res = **ip;
+               res = *p;
        }
-       
+       *ip = p;
        return res;
 }