This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / mono / dis / get.c
1 /*
2  * get.c: Functions to get stringified values from the metadata tables.
3  *
4  * Author:
5  *   Miguel de Icaza (miguel@ximian.com)
6  *
7  * (C) 2001 Ximian, Inc.
8  */
9 #include <config.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <ctype.h>
14 #include <glib.h>
15 #include "meta.h"
16 #include "util.h"
17 #include "get.h"
18 #include <mono/metadata/class.h>
19 #include <mono/metadata/marshal.h>
20
21 extern gboolean substitute_with_mscorlib_p;
22
23 static char *
24 get_memberref_parent (MonoImage *m, guint32 mrp_token);
25
26 GHashTable *key_table = NULL;
27 gboolean show_method_tokens = FALSE;
28 gboolean show_tokens = FALSE;
29
30 char *
31 get_typedef (MonoImage *m, int idx)
32 {
33         guint32 cols [MONO_TYPEDEF_SIZE];
34         const char *ns;
35         char *tstring, *result;
36         guint32 token;
37         
38         mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPEDEF], idx - 1, cols, MONO_TYPEDEF_SIZE);
39
40         ns = mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAMESPACE]);
41
42         /* Check if this is a nested type */
43         token = MONO_TOKEN_TYPE_DEF | (idx);
44         token = mono_metadata_nested_in_typedef (m, token);
45         tstring = show_tokens ? g_strdup_printf ("/*%08x*/", token) : NULL;
46         if (token) {
47                 char *outer;
48                 
49                 outer = get_typedef (m, mono_metadata_token_index (token));
50                 result = g_strdup_printf (
51                         "%s%s%s/%s%s", ns, *ns?".":"", outer,
52                         mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAME]),
53                         tstring ? tstring : "");
54                 g_free (outer);
55                 g_free (tstring);
56                 return result;
57         }
58         
59         
60         result = g_strdup_printf (
61                 "%s%s%s%s", ns, *ns?".":"",
62                 mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAME]),
63                 tstring ? tstring : "");
64         g_free (tstring);
65         return result;
66 }
67
68 char *
69 get_module (MonoImage *m, int idx)
70 {
71         guint32 cols [MONO_MODULE_SIZE];
72         
73         /*
74          * There MUST BE only one module in the Module table
75          */
76         g_assert (idx == 1);
77             
78         mono_metadata_decode_row (&m->tables [MONO_TABLE_MODULE], idx - 1, cols, MONO_MODULE_SIZE);
79
80         return g_strdup (mono_metadata_string_heap (m, cols [MONO_MODULE_NAME]));
81 }
82
83 char *
84 get_moduleref (MonoImage *m, int idx)
85 {
86         guint32 cols [MONO_MODULEREF_SIZE];
87         
88         mono_metadata_decode_row (&m->tables [MONO_TABLE_MODULEREF], idx - 1, cols, MONO_MODULEREF_SIZE);
89
90         return g_strdup (mono_metadata_string_heap (m, cols [MONO_MODULEREF_NAME]));
91 }
92
93 char *
94 get_assemblyref (MonoImage *m, int idx)
95 {
96         guint32 cols [MONO_ASSEMBLYREF_SIZE];
97         
98         mono_metadata_decode_row (&m->tables [MONO_TABLE_ASSEMBLYREF], idx - 1, cols, MONO_ASSEMBLYREF_SIZE);
99
100         return g_strdup (mono_metadata_string_heap (m, cols [MONO_ASSEMBLYREF_NAME]));
101 }
102
103 /*
104  *
105  * Returns a string representing the ArrayShape (22.2.16).
106  */
107 static const char *
108 get_array_shape (MonoImage *m, const char *ptr, char **result)
109 {
110         GString *res = g_string_new ("[");
111         guint32 rank, num_sizes, num_lo_bounds;
112         guint32 *sizes = NULL, *lo_bounds = NULL;
113         int i, r;
114         char buffer [80];
115         
116         rank = mono_metadata_decode_value (ptr, &ptr);
117         num_sizes = mono_metadata_decode_value (ptr, &ptr);
118
119         if (num_sizes > 0)
120                 sizes = g_new (guint32, num_sizes);
121         
122         for (i = 0; i < num_sizes; i++)
123                 sizes [i] = mono_metadata_decode_value (ptr, &ptr);
124
125         num_lo_bounds = mono_metadata_decode_value (ptr, &ptr);
126         if (num_lo_bounds > 0)
127                 lo_bounds = g_new (guint32, num_lo_bounds);
128         
129         for (i = 0; i < num_lo_bounds; i++)
130                 lo_bounds [i] = mono_metadata_decode_value (ptr, &ptr);
131
132         for (r = 0; r < rank; r++){
133                 if (r < num_sizes){
134                         if (r < num_lo_bounds){
135                                 sprintf (buffer, "%d..%d", lo_bounds [r], lo_bounds [r] + sizes [r] - 1);
136                         } else {
137                                 sprintf (buffer, "0..%d", sizes [r] - 1);
138                         }
139                 } else
140                         buffer [0] = 0;
141                 
142                 g_string_append (res, buffer);
143                 if ((r + 1) != rank)
144                         g_string_append (res, ", ");
145         }
146         g_string_append (res, "]");
147         
148         if (sizes)
149                 g_free (sizes);
150
151         if (lo_bounds)
152                 g_free (lo_bounds);
153
154         *result = res->str;
155         g_string_free (res, FALSE);
156
157         return ptr;
158 }
159
160 /**
161  * get_typespec:
162  * @m: metadata context
163  * @blob_idx: index into the blob heap
164  *
165  * Returns the stringified representation of a TypeSpec signature (22.2.17)
166  */
167 char *
168 get_typespec (MonoImage *m, guint32 idx)
169 {
170         guint32 cols [MONO_TYPESPEC_SIZE];
171         const char *ptr;
172         char *s, *result;
173         GString *res = g_string_new ("");
174         int len;
175
176         MonoType *type;
177
178         type = mono_type_create_from_typespec (m, idx);
179                 
180         mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPESPEC], idx-1, cols, MONO_TYPESPEC_SIZE);
181         ptr = mono_metadata_blob_heap (m, cols [MONO_TYPESPEC_SIGNATURE]);
182         len = mono_metadata_decode_value (ptr, &ptr);
183         
184         switch (*ptr++){
185         case MONO_TYPE_PTR:
186                 ptr = get_custom_mod (m, ptr, &s);
187                 if (s){
188                         g_string_append (res, s);
189                         g_string_append_c (res, ' ');
190                         g_free (s);
191                 }
192                 
193                 if (*ptr == MONO_TYPE_VOID)
194                         g_string_append (res, "void");
195                 else {
196                         ptr = get_type (m, ptr, &s);
197                         if (s)
198                                 g_string_append (res, s);
199                 }
200                 g_string_append (res, "*");
201                 break;
202                 
203         case MONO_TYPE_FNPTR:
204                 s = dis_stringify_function_ptr (m, type->data.method);
205                 g_string_append (res, "method ");
206                 g_string_append (res, s);
207                 g_free (s);
208                 break;
209                         
210         case MONO_TYPE_ARRAY:
211                 ptr = get_type (m, ptr, &s);
212                 g_string_append (res, s);
213                 g_free (s);
214                 g_string_append_c (res, ' ');
215                 ptr = get_array_shape (m, ptr, &s);
216                 g_string_append (res, s);
217                 g_free (s);
218                 break;
219                 
220         case MONO_TYPE_SZARRAY:
221                 ptr = get_custom_mod (m, ptr, &s);
222                 if (s){
223                         g_string_append (res, s);
224                         g_string_append_c (res, ' ');
225                         g_free (s);
226                 }
227                 ptr = get_type (m, ptr, &s);
228                 g_string_append (res, s);
229                 g_string_append (res, "[]");
230                 g_free (s);
231                 break;
232
233         case MONO_TYPE_VAR:
234         case MONO_TYPE_MVAR:
235                 ptr = get_type (m, ptr-1, &s);
236                 g_string_append (res, s);
237                 g_free (s);
238                 break;
239                 
240         default:
241                 s = dis_stringify_type (m, type);
242                 g_string_append (res, s);
243                 g_free (s);
244                 break;
245         }
246
247         if (show_tokens) {
248                 int token = mono_metadata_make_token (MONO_TABLE_TYPESPEC, idx);
249                 result = g_strdup_printf ("%s/*%08x*/", res->str, token);
250         } else
251                 result = res->str;
252
253         g_string_free (res, FALSE);
254
255         return result;
256 }
257
258 char *
259 get_typeref (MonoImage *m, int idx)
260 {
261         guint32 cols [MONO_TYPEREF_SIZE];
262         const char *s, *t;
263         char *x, *ret;
264         guint32 rs_idx, table;
265         
266         mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPEREF], idx - 1, cols, MONO_TYPEREF_SIZE);
267
268         t = mono_metadata_string_heap (m, cols [MONO_TYPEREF_NAME]);
269         s = mono_metadata_string_heap (m, cols [MONO_TYPEREF_NAMESPACE]);
270
271         rs_idx = cols [MONO_TYPEREF_SCOPE] >> MONO_RESOLTION_SCOPE_BITS;
272         table = cols [MONO_TYPEREF_SCOPE] & MONO_RESOLTION_SCOPE_MASK;
273         
274         switch (table){
275         case MONO_RESOLTION_SCOPE_MODULE: /* Module */
276                 x = get_module (m, rs_idx);
277                 ret = g_strdup_printf ("[%s] %s%s%s", x, s, *s?".":"", t);
278                 g_free (x);
279                 break;
280
281         case MONO_RESOLTION_SCOPE_MODULEREF: /* ModuleRef */
282                 x = get_moduleref (m, rs_idx);
283                 ret = g_strdup_printf ("[.module %s]%s%s%s", x, s, *s ? "." : "", t);
284                 break;
285                               
286         case MONO_RESOLTION_SCOPE_ASSEMBLYREF: /*
287                  * AssemblyRef (ECMA docs claim it is 3, but it looks to
288                  * me like it is 2 (tokens are prefixed with 0x23)
289                  */
290                 x = get_assemblyref (m, rs_idx);
291                 ret = g_strdup_printf ("[%s]%s%s%s", x, s, *s?".":"", t);
292                 g_free (x);
293                 break;
294                 
295         case MONO_RESOLTION_SCOPE_TYPEREF: /* TypeRef */
296                 x = get_typeref (m, rs_idx);
297                 ret =  g_strdup_printf ("%s/%s", x, t);
298                 g_free (x);
299                 break;
300                 
301         default:
302                 ret = g_strdup_printf ("Unknown table in TypeRef %d", table);
303         }
304
305         if (show_tokens) {
306                 int token = mono_metadata_make_token (MONO_TABLE_TYPEREF, idx);
307                 char *temp = g_strdup_printf ("%s/*%08x*/", ret, token);
308                 g_free (ret);
309                 ret = temp;
310         }
311
312         return ret;
313 }
314
315 /**
316  * get_typedef_or_ref:
317  * @m: metadata context
318  * @dor_token: def or ref encoded index
319  *
320  * Low two bits contain table to lookup from
321  * high bits contain the index into the def or ref table
322  *
323  * Returns: a stringified version of the MethodDef or MethodRef
324  * at (dor_token >> 2) 
325  */
326 char *
327 get_typedef_or_ref (MonoImage *m, guint32 dor_token)
328 {
329         char *temp = NULL, *s = NULL;
330         int table, idx;
331
332         /*
333          * low 2 bits contain encoding
334          */
335         table = dor_token & MONO_TYPEDEFORREF_MASK;
336         idx = dor_token >> MONO_TYPEDEFORREF_BITS;
337         
338         switch (table){
339         case 0: /* TypeDef */
340                 temp = get_typedef (m, idx);
341                 s = g_strdup_printf ("%s", temp);
342                 break;
343                 
344         case 1: /* TypeRef */
345                 temp = get_typeref (m, idx);
346                 s = g_strdup_printf ("%s", temp);
347                 break;
348                 
349         case 2: /* TypeSpec */
350                 s = get_typespec (m, idx);
351                 break;
352
353         default:
354                 g_error ("Unhandled encoding for typedef-or-ref coded index 0x%08x", dor_token);
355
356         }
357         
358         if (temp)
359                 g_free (temp);
360
361         return s;
362 }
363
364 /**
365  * get_type_or_methdef
366  * @m: metadata context
367  * @dor_token: type or method def encoded index
368  *
369  * Low bit contains the table to lookup from
370  * high bits contain the index into the type def or method def table
371  *
372  * Returns: a stringified version of the TypeOrMethodDef token
373  */
374 char *
375 get_type_or_methdef (MonoImage *m, guint32 dor_token)
376 {
377         if (dor_token & MONO_TYPEORMETHOD_METHOD) /* MethodDef */
378                 return get_methoddef (m, dor_token >> MONO_TYPEORMETHOD_BITS);
379         else  /* TypeDef */
380                 return get_typedef (m, dor_token >> MONO_TYPEORMETHOD_BITS);
381 }
382
383 /** 
384  * get_encoded_typedef_or_ref:
385  * @m: metadata context 
386  * @ptr: location to decode from.
387  * @result: pointer to string where resulting decoded string is stored
388  *
389  * result will point to a g_malloc()ed string.
390  *
391  * Returns: the new ptr to continue decoding
392  */
393 const char *
394 get_encoded_typedef_or_ref (MonoImage *m, const char *ptr, char **result)
395 {
396         guint32 token;
397         
398         token = mono_metadata_decode_value (ptr, &ptr);
399
400         *result = get_typedef_or_ref (m, token);
401
402         return ptr;
403 }
404
405 /**
406  * get_custom_mod:
407  *
408  * Decodes a CustomMod (22.2.7)
409  *
410  * Returns: updated pointer location
411  */
412 const char *
413 get_custom_mod (MonoImage *m, const char *ptr, char **return_value)
414 {
415         char *s;
416         const char *reqd;
417         
418         *return_value = NULL;
419         while ((*ptr == MONO_TYPE_CMOD_OPT) ||
420                    (*ptr == MONO_TYPE_CMOD_REQD)) {
421                 reqd = (*ptr == MONO_TYPE_CMOD_REQD) ? "reqd" : "opt";
422                 ptr++;
423                 ptr = get_encoded_typedef_or_ref (m, ptr, &s);
424
425                 if (*return_value == NULL)
426                         *return_value = g_strconcat (reqd, " ", s, NULL);
427                 else
428                         *return_value = g_strconcat (*return_value, " ", reqd, " ", s, NULL);
429                 g_free (s);
430         }
431         return ptr;
432 }
433
434
435 static dis_map_t element_type_map [] = {
436         { MONO_TYPE_END        , "end" },
437         { MONO_TYPE_VOID       , "void" },
438         { MONO_TYPE_BOOLEAN    , "bool" },
439         { MONO_TYPE_CHAR       , "char" }, 
440         { MONO_TYPE_I1         , "int8" },
441         { MONO_TYPE_U1         , "unsigned int8" }, 
442         { MONO_TYPE_I2         , "int16" },
443         { MONO_TYPE_U2         , "unsigned int16" },
444         { MONO_TYPE_I4         , "int32" },
445         { MONO_TYPE_U4         , "unsigned int32" },
446         { MONO_TYPE_I8         , "int64" },
447         { MONO_TYPE_U8         , "unsigned int64" },
448         { MONO_TYPE_R4         , "float32" },
449         { MONO_TYPE_R8         , "float64" },
450         { MONO_TYPE_STRING     , "string" },
451         { MONO_TYPE_TYPEDBYREF , "TypedByRef" },
452         { MONO_TYPE_I          , "native int" },
453         { MONO_TYPE_U          , "native unsigned int" },
454         { MONO_TYPE_OBJECT     , "object" },
455         { 0, NULL }
456 };
457
458 static dis_map_t call_conv_type_map [] = {
459         { MONO_CALL_DEFAULT     , "default" },
460         { MONO_CALL_C           , "c" },
461         { MONO_CALL_STDCALL     , "stdcall" },
462         { MONO_CALL_THISCALL    , "thiscall" },
463         { MONO_CALL_FASTCALL    , "fastcall" },
464         { MONO_CALL_VARARG      , "vararg" },
465         { 0, NULL }
466 };
467
468 char*
469 dis_stringify_token (MonoImage *m, guint32 token)
470 {
471         guint idx = token & 0xffffff;
472         switch (token >> 24) {
473         case MONO_TABLE_TYPEDEF: return get_typedef (m, idx);
474         case MONO_TABLE_TYPEREF: return get_typeref (m, idx);
475         case MONO_TABLE_TYPESPEC: return get_typespec (m, idx);
476         default:
477                  break;
478         }
479         return g_strdup_printf("0x%08x", token);
480 }
481
482 char*
483 dis_stringify_array (MonoImage *m, MonoArrayType *array) 
484 {
485         char *type;
486         GString *s = g_string_new("");
487         int i;
488         
489         type = dis_stringify_type (m, &array->eklass->byval_arg);
490         g_string_append (s, type);
491         g_free (type);
492         g_string_append_c (s, '[');
493         for (i = 0; i < array->rank; ++i) {
494                 if (i)
495                         g_string_append_c (s, ',');
496                 if (i < array->numsizes) {
497                         if (i < array->numlobounds && array->lobounds[i] != 0)
498                                 g_string_sprintfa (s, "%d..%d", array->lobounds[i], array->sizes[i]);
499                         else
500                                 g_string_sprintfa (s, "%d", array->sizes[i]);
501                 }
502         }
503         g_string_append_c (s, ']');
504         type = s->str;
505         g_string_free (s, FALSE);
506         return type;
507 }
508
509 char*
510 dis_stringify_modifiers (MonoImage *m, int n, MonoCustomMod *mod)
511 {
512         GString *s = g_string_new("");
513         char *result;
514         int i;
515         for (i = 0; i < n; ++i) {
516                 char *tok = dis_stringify_token (m, mod[i].token);
517                 if (i > 0)
518                         g_string_sprintfa (s, " ");
519                 g_string_sprintfa (s, "%s (%s)", mod[i].required ? "modreq": "modopt", tok);
520                 g_free (tok);
521         }
522         g_string_append_c (s, ' ');
523         result = s->str;
524         g_string_free (s, FALSE);
525         return result;
526 }
527
528 char*
529 dis_stringify_param (MonoImage *m, MonoType *param) 
530 {
531         char *t;
532         char *result;
533         const char *out = param->attrs & 2 ? "[out] ": "";
534         t = dis_stringify_type (m, param);
535         result = g_strconcat (out, t, NULL);
536         g_free (t);
537         return result;
538 }
539
540 /**
541  * get_generic_param
542  * @m: metadata context 
543  * @table_type: The type of table we are getting generics for (0 for typedef, 1 for method)
544  * @row: The row in the table
545  *
546  * Returns: Allocated stringified generic parameters
547  */
548 char*
549 get_generic_param (MonoImage *m, int table_type, guint32 row)
550 {
551         MonoTableInfo *t = &m->tables [MONO_TABLE_GENERICPARAM];
552         GString *result = g_string_new ("");
553         char *retval;
554         guint32 cols [MONO_GENERICPARAM_SIZE];
555         int i, own_tok, table, idx, found_count;
556
557         g_assert (table_type != MONO_TYPEORMETHOD_TYPE || table_type != MONO_TYPEORMETHOD_METHOD);
558         
559         found_count = 0;
560         for (i = 1; i <= t->rows; i++) {
561                 mono_metadata_decode_row (t, i-1, cols, MONO_GENERICPARAM_SIZE);
562                 own_tok = cols [MONO_GENERICPARAM_OWNER];
563                 table = own_tok & MONO_TYPEORMETHOD_MASK;
564                 idx = own_tok >> MONO_TYPEORMETHOD_BITS;
565                 
566                 if (table != table_type || idx != row)
567                         continue;
568
569                 if (found_count == 0)
570                         g_string_append_printf (result, "<%s",
571                                         mono_metadata_string_heap (m, cols [MONO_GENERICPARAM_NAME]));
572                 else
573                         g_string_append_printf (result, ", %s",
574                                         mono_metadata_string_heap (m, cols [MONO_GENERICPARAM_NAME]));
575                 found_count++;
576         }
577
578         if (found_count)
579                 g_string_append_c (result, '>');
580         retval = result->str;
581         g_string_free (result, FALSE);
582         return retval;
583 }
584
585 char*
586 dis_stringify_method_signature (MonoImage *m, MonoMethodSignature *method, int methoddef_row, gboolean fully_qualified)
587 {
588         guint32 cols [MONO_METHOD_SIZE];
589         guint32 pcols [MONO_PARAM_SIZE];
590         guint32 param_index = 0;
591         const char *name = "";
592         int free_method = 0;
593         char *retval, *esname;
594         char *type = NULL;
595         char *gen_param = NULL;
596         GString *result = g_string_new ("");
597         int i;
598         
599         g_assert (method || methoddef_row);
600
601         if (methoddef_row) {
602                 mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD], methoddef_row -1, cols, MONO_METHOD_SIZE);
603                 if (fully_qualified)
604                         type = get_typedef (m, mono_metadata_typedef_from_method (m, methoddef_row));
605                 name = mono_metadata_string_heap (m, cols [MONO_METHOD_NAME]);
606                 param_index = cols [MONO_METHOD_PARAMLIST];
607                 if (!method) {
608                         const char *sig = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]);
609                         mono_metadata_decode_blob_size (sig, &sig);
610                         method = mono_metadata_parse_method_signature (m, methoddef_row, sig, &sig);
611                         free_method = 1;
612                 }      
613                 gen_param = get_generic_param (m, 1, methoddef_row);
614         }
615         
616         retval = dis_stringify_param (m, method->ret);
617         if (method->hasthis)
618                 g_string_append (result, "instance ");
619         g_string_append (result, map (method->call_convention, call_conv_type_map));
620         g_string_sprintfa (result, " %s ", retval);
621         if (type) {
622                 char *estype = get_escaped_name (type);
623                 g_string_sprintfa (result, "%s::", estype);
624                 g_free (estype);
625         }
626         esname = get_escaped_name (name);
627         g_string_append (result, esname);
628         g_free (esname);
629         if (gen_param) {
630                 g_string_append (result, gen_param);
631                 g_free (gen_param);
632         }
633         g_string_append (result, " (");
634         g_free (retval);
635         for (i = 0; i < method->param_count; ++i) {
636                 if (param_index && param_index <= m->tables [MONO_TABLE_PARAM].rows) {
637                         mono_metadata_decode_row (&m->tables [MONO_TABLE_PARAM], param_index - 1, pcols, MONO_PARAM_SIZE);
638                         name = mono_metadata_string_heap (m, pcols [MONO_PARAM_NAME]);
639                         method->params [i]->attrs = pcols [MONO_PARAM_FLAGS];
640                         param_index++;
641                 } else {
642                         name = "";
643                 }
644                 if (i)
645                         g_string_append (result, ", ");
646                 retval = dis_stringify_param (m, method->params [i]);
647                 esname = get_escaped_name (name);
648                 g_string_append_printf (result, "%s %s", retval, esname);
649                 g_free (retval);
650                 g_free (esname);
651         }
652         g_string_append (result, ") ");
653
654         if (show_method_tokens && methoddef_row)
655                 g_string_append_printf (result, " /* 0x%X */ ",
656                                 (methoddef_row >> MONO_TYPEORMETHOD_BITS) | MONO_TOKEN_METHOD_DEF);
657
658         if (free_method)
659                 mono_metadata_free_method_signature (method);
660         retval = result->str;
661         g_string_free (result, FALSE);
662
663         return retval;
664 }
665
666 char*
667 dis_stringify_function_ptr (MonoImage *m, MonoMethodSignature *method)
668 {
669         char *retval;
670         GString *result = g_string_new ("");
671         int i;
672         
673         g_assert (method);
674
675         g_string_append (result, map (method->call_convention, call_conv_type_map));
676
677         retval = dis_stringify_param (m, method->ret);
678         g_string_sprintfa (result, " %s ", retval);
679         g_free (retval);
680
681         g_string_append (result, " *(");
682         for (i = 0; i < method->param_count; ++i) {
683                 if (i)
684                         g_string_append (result, ", ");
685                 retval = dis_stringify_param (m, method->params [i]);
686                 g_string_append (result, retval);
687                 g_free (retval);
688         }
689         g_string_append (result, ") ");
690
691         retval = result->str;
692         g_string_free (result, FALSE);
693
694         return retval;
695 }
696
697 static char *
698 dis_stringify_object_with_class (MonoImage *m, MonoClass *c)
699 {
700         /* FIXME: handle MONO_TYPE_OBJECT ... */
701         const char *otype = c->byval_arg.type == MONO_TYPE_CLASS? "class" : "valuetype";
702         char *assemblyref = NULL, *result, *esname;
703         if (m != c->image) {
704                 if (c->image->assembly_name) {
705                         /* we cheat */
706                         if (substitute_with_mscorlib_p && !strcmp ("corlib", c->image->assembly_name))
707                                 assemblyref = g_strdup_printf ("[%s]", "mscorlib");
708                         else
709                                 assemblyref = g_strdup_printf ("[%s]", c->image->assembly->aname.name);
710                 } else {
711                         assemblyref = g_strdup_printf ("[.module %s]", c->image->module_name);
712                 }
713         }
714
715         if (c->nested_in) {
716                 result = g_strdup_printf ("%s%s%s/%s", c->nested_in->name_space, 
717                                 *c->nested_in->name_space?".":"", c->nested_in->name,
718                                 c->name);
719         } else {
720                 result = g_strdup_printf ("%s%s%s", c->name_space, 
721                                 *c->name_space?".":"", c->name);
722         }
723         
724         esname = get_escaped_name (result);
725         g_free (result);
726
727         result = g_strdup_printf ("%s %s%s", otype, assemblyref?assemblyref:"", esname);
728         
729         g_free (assemblyref);
730         g_free (esname);
731         
732         return result;
733 }
734
735 static char *
736 dis_stringify_object (MonoImage *m, MonoType *type)
737 {
738         MonoClass *c = mono_class_from_mono_type (type);
739         return dis_stringify_object_with_class (m, c);
740 }
741
742 char*
743 dis_stringify_type (MonoImage *m, MonoType *type)
744 {
745         const char *pinned = "", *byref = "";
746         char *bare = NULL, *mods = NULL;
747         char *result;
748
749         if (type->num_mods)
750                 mods = dis_stringify_modifiers (m, type->num_mods, type->modifiers);
751
752         switch (type->type){
753         case MONO_TYPE_BOOLEAN:
754         case MONO_TYPE_CHAR:
755         case MONO_TYPE_I1:
756         case MONO_TYPE_U1:
757         case MONO_TYPE_I2:
758         case MONO_TYPE_U2:
759         case MONO_TYPE_I4:
760         case MONO_TYPE_U4:
761         case MONO_TYPE_I8:
762         case MONO_TYPE_U8:
763         case MONO_TYPE_R4:
764         case MONO_TYPE_R8:
765         case MONO_TYPE_I:
766         case MONO_TYPE_U:
767         case MONO_TYPE_STRING:
768         case MONO_TYPE_OBJECT:
769         case MONO_TYPE_TYPEDBYREF:
770                 bare = g_strdup (map (type->type, element_type_map));
771                 break;
772                 
773         case MONO_TYPE_VALUETYPE:
774         case MONO_TYPE_CLASS:
775                 bare = dis_stringify_object (m, type);
776                 break;
777         case MONO_TYPE_FNPTR: {
778                 char *child_type;
779                 child_type = dis_stringify_function_ptr (m, type->data.method);
780                 bare = g_strdup_printf ("method %s", child_type);
781                 g_free (child_type);
782                 break;
783         }
784         case MONO_TYPE_PTR: {
785                 char *child_type;
786                 child_type = dis_stringify_type (m, type->data.type);
787                 
788                 bare = g_strdup_printf ("%s*", child_type);
789                 g_free (child_type);
790                 break;
791         }
792         case MONO_TYPE_SZARRAY: {
793                 char *child_type;
794                 child_type = dis_stringify_type (m, &type->data.klass->byval_arg);
795                 
796                 bare = g_strdup_printf ("%s[]", child_type);
797                 g_free (child_type);
798                 break;
799         }
800         case MONO_TYPE_ARRAY:
801                 bare = dis_stringify_array (m, type->data.array);
802                 break;
803         case MONO_TYPE_VOID:
804                 bare = g_strdup ("void");
805                 break;
806         case MONO_TYPE_MVAR:
807                 bare = g_strdup_printf ("!!%d", type->data.generic_param->num);
808                 break;
809         case MONO_TYPE_VAR:
810                 bare = g_strdup_printf ("!%d", type->data.generic_param->num);
811                 break;
812         case MONO_TYPE_GENERICINST: {
813                 GString *str = g_string_new ("");
814                 int i;
815                 char *generic_type = dis_stringify_type (m, type->data.generic_inst->generic_type);
816
817                 for (i = 0; i < type->data.generic_inst->type_argc; i++){
818                         char *t = dis_stringify_type (m, type->data.generic_inst->type_argv [i]);
819
820                         g_string_append (str, t);
821                         if (i+1 != type->data.generic_inst->type_argc)
822                                 g_string_append (str, ", ");
823                         g_free (t);
824                 }
825                 bare = g_strdup_printf ("%s<%s>", generic_type, str->str);
826                 g_string_free (str, TRUE);
827                 break;
828         }
829                 
830         default:
831                 g_error ("Do not know how to stringify type 0x%x", type->type);
832         }
833         
834         if (type->pinned)
835                 pinned = " pinned";
836
837         if (type->byref)
838                 byref = "&";
839                 
840         result = g_strconcat (mods ? mods : "", bare, byref, pinned, NULL);
841
842         g_free (bare);
843
844         return result;
845 }
846
847 /**
848  * get_type:
849  * @m: metadata context 
850  * @ptr: location to decode from.
851  * @result: pointer to string where resulting decoded string is stored
852  *
853  * This routine returs in @result the stringified type pointed by @ptr.
854  * (22.2.12)
855  *
856  * Returns: the new ptr to continue decoding
857  */
858 const char *
859 get_type (MonoImage *m, const char *ptr, char **result)
860 {
861         const char *start = ptr;
862         guint32 type;
863         MonoType *t;
864
865         if (*ptr == MONO_TYPE_BYREF)
866                 ++ptr;
867
868         type = mono_metadata_decode_value (ptr, &ptr);
869
870         switch (type){
871         case MONO_TYPE_VALUETYPE:
872         case MONO_TYPE_CLASS: {
873                 guint32 token = mono_metadata_parse_typedef_or_ref (m, ptr, &ptr);
874                 MonoClass *klass = mono_class_get (m, token);
875                 char *temp = dis_stringify_object_with_class (m, klass);
876
877                 if (show_tokens) {
878                         *result = g_strdup_printf ("%s/*%08x*/", temp, token);
879                         g_free (temp);
880                 } else
881                         *result = temp;
882                 break;
883         }
884
885         case MONO_TYPE_GENERICINST: {
886                 GString *str = g_string_new ("");
887                 int count, i;
888                 char *temp;
889
890                 ptr = get_type (m, ptr, &temp);
891                 g_string_append (str, temp);
892                 g_free (temp);
893
894                 count = mono_metadata_decode_value (ptr, &ptr);
895                 g_string_append (str, "<");
896
897                 for (i = 0; i < count; i++) {
898                         if (i)
899                                 g_string_append (str, ",");
900                         ptr = get_type (m, ptr, &temp);
901                         g_string_append (str, temp);
902                 }
903
904                 g_string_append (str, ">");
905                 *result = str->str;
906                 g_string_free (str, FALSE);
907                 break;
908         }
909
910         default:
911                 t = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, start, &ptr);
912                 *result = dis_stringify_type (m, t);
913                 mono_metadata_free_type (t);
914                 break;
915         }
916
917         return ptr;
918 }
919
920 /**
921  * 
922  * Returns a stringified representation of a FieldSig (22.2.4)
923  */
924 char *
925 get_field_signature (MonoImage *m, guint32 blob_signature)
926 {
927         char *allocated_modifier_string, *allocated_type_string;
928         const char *ptr = mono_metadata_blob_heap (m, blob_signature);
929         const char *base;
930         char *res;
931         int len;
932         
933         len = mono_metadata_decode_value (ptr, &ptr);
934         base = ptr;
935         /* FIELD is 0x06 */
936         g_assert (*ptr == 0x06);
937 /*      hex_dump (ptr, 0, len); */
938         ptr++; len--;
939         
940         ptr = get_custom_mod (m, ptr, &allocated_modifier_string);
941         ptr = get_type (m, ptr, &allocated_type_string);
942
943         res = g_strdup_printf (
944                 "%s %s",
945                 allocated_modifier_string ? allocated_modifier_string : "",
946                 allocated_type_string);
947         
948         if (allocated_modifier_string)
949                 g_free (allocated_modifier_string);
950         if (allocated_type_string)
951                 g_free (allocated_type_string);
952         
953         return res;
954 }
955
956 MonoTypeEnum
957 get_field_literal_type (MonoImage *m, guint32 blob_signature)
958 {
959         const char *ptr = mono_metadata_blob_heap (m, blob_signature);
960         int len;
961         char *allocated_modifier_string;
962         
963         len = mono_metadata_decode_value (ptr, &ptr);
964
965         /* FIELD is 0x06 */
966         g_assert (*ptr == 0x06);
967         ptr++; len--;
968         
969         ptr = get_custom_mod (m, ptr, &allocated_modifier_string);
970         if (allocated_modifier_string)
971                 g_free (allocated_modifier_string);
972
973         return (MonoTypeEnum) *ptr;
974         
975 }
976
977 /**
978  * decode_literal:
979  * @m: metadata context
980  * @token: token to decode
981  *
982  * decodes the literal indexed by @token.
983  */
984 char *
985 decode_literal (MonoImage *m, guint32 token)
986 {
987         return g_strdup ("LITERAL_VALUE");
988 }
989
990 /**
991  * get_ret_type:
992  * @m: metadata context 
993  * @ptr: location to decode from.
994  * @result: pointer to string where resulting decoded string is stored
995  *
996  * This routine returns in @result the stringified RetType (22.2.11)
997  *
998  * Returns: the new ptr to continue decoding.
999  */
1000 const char *
1001 get_ret_type (MonoImage *m, const char *ptr, char **ret_type)
1002 {
1003         GString *str = g_string_new ("");
1004         char *mod = NULL;
1005         char *allocated_type_string;
1006         
1007         ptr = get_custom_mod (m, ptr, &mod);
1008         if (mod){
1009                 g_string_append (str, mod);
1010                 g_string_append_c (str, ' ');
1011                 g_free (mod);
1012         }
1013
1014         if (*ptr == MONO_TYPE_TYPEDBYREF){
1015                 g_string_append (str, "typedbyref");
1016                 ptr++;
1017         } else if (*ptr == MONO_TYPE_VOID){
1018                  g_string_append (str, "void");
1019                  ptr++;
1020         } else {
1021                 if (*ptr == MONO_TYPE_BYREF){
1022                         g_string_append (str, "[out] ");
1023                         ptr++;
1024                 }
1025
1026                 ptr = get_type (m, ptr, &allocated_type_string);
1027                 g_string_append (str, allocated_type_string);
1028                 g_free (allocated_type_string);
1029         }
1030
1031         *ret_type = str->str;
1032         g_string_free (str, FALSE);
1033
1034         return ptr;
1035 }
1036
1037 /**
1038  * get_param:
1039  * @m: metadata context 
1040  * @ptr: location to decode from.
1041  * @result: pointer to string where resulting decoded string is stored
1042  *
1043  * This routine returns in @result the stringified Param (22.2.10)
1044  *
1045  * Returns: the new ptr to continue decoding.
1046  */
1047 const char *
1048 get_param (MonoImage *m, const char *ptr, char **retval)
1049 {
1050         GString *str = g_string_new ("");
1051         char *allocated_mod_string, *allocated_type_string;
1052         
1053         ptr = get_custom_mod (m, ptr, &allocated_mod_string);
1054         if (allocated_mod_string){
1055                 g_string_append (str, allocated_mod_string);
1056                 g_string_append_c (str, ' ');
1057                 g_free (allocated_mod_string);
1058         }
1059         
1060         if (*ptr == MONO_TYPE_TYPEDBYREF){
1061                 g_string_append (str, " typedbyref ");
1062                 ptr++;
1063         } else {
1064                 gboolean by_ref = 0;
1065                  if (*ptr == MONO_TYPE_BYREF){
1066                         g_string_append (str, "[out] ");
1067                         ptr++;
1068                         by_ref = 1;
1069                 }
1070                 ptr = get_type (m, ptr, &allocated_type_string);
1071                 g_string_append (str, allocated_type_string);
1072                 if (by_ref)
1073                         g_string_append_c (str, '&');
1074                 g_free (allocated_type_string);
1075         }
1076
1077         *retval = str->str;
1078         g_string_free (str, FALSE);
1079         return ptr;
1080 }
1081
1082 /**
1083  * get_escaped_name
1084  *
1085  * Returns: An allocated escaped name. A name needs to be escaped
1086  * because it might be an ilasm keyword.
1087  */
1088 char*
1089 get_escaped_name (const char *name)
1090 {
1091         const char *s;
1092
1093         g_assert (key_table);
1094
1095         if (strlen (name) == 0)
1096                 return g_strdup (name);
1097
1098         for (s = name; *s; s++) {
1099                 if (isalnum (*s) || *s == '_' || *s == '$' || *s == '@' || *s == '?' || *s == '.' || *s == 0)
1100                         continue;
1101                 return g_strdup_printf ("'%s'", name);
1102         }
1103         
1104         if (g_hash_table_lookup (key_table, name))
1105                 return g_strdup_printf ("'%s'", name);
1106                         
1107         return g_strdup (name);
1108 }
1109
1110 static dis_map_t param_map [] = {
1111         { PARAM_ATTRIBUTE_IN,                "[in] " },
1112         { PARAM_ATTRIBUTE_OUT,               "[out] " },
1113         { PARAM_ATTRIBUTE_OPTIONAL,          "optional " },
1114         { PARAM_ATTRIBUTE_HAS_DEFAULT,       "hasdefault " },
1115         { PARAM_ATTRIBUTE_HAS_FIELD_MARSHAL, "fieldmarshal " },
1116         { 0, NULL }
1117 };
1118
1119 char *
1120 param_flags (guint32 f)
1121 {
1122         return g_strdup (flags (f, param_map));
1123 }
1124
1125 static dis_map_t field_access_map [] = {
1126         { FIELD_ATTRIBUTE_COMPILER_CONTROLLED, "compilercontrolled " },
1127         { FIELD_ATTRIBUTE_PRIVATE,             "private " },
1128         { FIELD_ATTRIBUTE_FAM_AND_ASSEM,       "famandassem " },
1129         { FIELD_ATTRIBUTE_ASSEMBLY,            "assembly " },
1130         { FIELD_ATTRIBUTE_FAMILY,              "family " },
1131         { FIELD_ATTRIBUTE_FAM_OR_ASSEM,        "famorassem " },
1132         { FIELD_ATTRIBUTE_PUBLIC,              "public " },
1133         { 0, NULL }
1134 };
1135
1136 static dis_map_t field_flags_map [] = {
1137         { FIELD_ATTRIBUTE_STATIC,              "static " },
1138         { FIELD_ATTRIBUTE_INIT_ONLY,           "initonly " },
1139         { FIELD_ATTRIBUTE_LITERAL,             "literal " },
1140         { FIELD_ATTRIBUTE_NOT_SERIALIZED,      "notserialized " },
1141         { FIELD_ATTRIBUTE_SPECIAL_NAME,        "specialname " },
1142         { FIELD_ATTRIBUTE_PINVOKE_IMPL,        "FIXME:pinvokeimpl " },
1143         { FIELD_ATTRIBUTE_RT_SPECIAL_NAME,        "rtspecialname " },
1144         { FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL,        "hasfieldmarshal " },
1145         { 0, NULL }
1146 };
1147
1148 /**
1149  * field_flags:
1150  *
1151  * Returns a stringified version of a Field's flags
1152  */
1153 char *
1154 field_flags (guint32 f)
1155 {
1156         char buffer [1024];
1157         int access = f & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK;
1158         
1159         buffer [0] = 0;
1160
1161         strcat (buffer, map (access, field_access_map));
1162         strcat (buffer, flags (f, field_flags_map));
1163         return g_strdup (buffer);
1164 }
1165
1166 /**
1167  * Returns a stringifed representation of a MethodRefSig (22.2.2)
1168  */
1169 char *
1170 get_methodref_signature (MonoImage *m, guint32 blob_signature, const char *fancy_name)
1171 {
1172         GString *res = g_string_new ("");
1173         const char *ptr = mono_metadata_blob_heap (m, blob_signature);
1174         char *allocated_ret_type, *s;
1175         gboolean has_vararg = 0, seen_vararg = 0;
1176         int param_count, signature_len;
1177         int i, gen_count = 0;
1178         int cconv;
1179         
1180         signature_len = mono_metadata_decode_value (ptr, &ptr);
1181
1182         if (*ptr & 0x05){
1183                 g_string_append (res, "vararg ");
1184                 has_vararg = 1;
1185         }
1186
1187         if (*ptr & 0x20){
1188                 if (*ptr & 0x40)
1189                         g_string_append (res, "explicit-this ");
1190                 else
1191                         g_string_append (res, "instance "); /* has-this */
1192         }
1193
1194         if (*ptr & 0x10)
1195                 gen_count = 1;
1196         cconv = *ptr & 0x0f;
1197         ptr++;
1198         if (gen_count)
1199                 gen_count = mono_metadata_decode_value (ptr, &ptr);
1200         param_count = mono_metadata_decode_value (ptr, &ptr);
1201         if (cconv != 0xa) {
1202                 ptr = get_ret_type (m, ptr, &allocated_ret_type);
1203                 g_string_append (res, allocated_ret_type);
1204                 g_free (allocated_ret_type);
1205         }
1206
1207         if (fancy_name){
1208                 g_string_append_c (res, ' ');
1209                 g_string_append (res, fancy_name);
1210         }
1211         
1212         g_string_append (res, "(");
1213
1214         /*
1215          * param_count describes parameters *before* and *after*
1216          * the vararg sentinel
1217          */
1218         for (i = 0; i < param_count; i++){
1219                 char *param = NULL;
1220                 
1221                 /*
1222                  * If ptr is a SENTINEL
1223                  */
1224                 if (*ptr == 0x41){
1225                         if (!seen_vararg){
1226                                 g_string_append (res, "..., ");
1227                                 seen_vararg = 1;
1228                         }
1229
1230                         ptr++;
1231                 }
1232
1233                 ptr = get_param (m, ptr, &param);
1234                 g_string_append (res, param);
1235                 if (i+1 != param_count)
1236                         g_string_append (res, ", ");
1237                 g_free (param);
1238         }
1239         g_string_append (res, ")");
1240         
1241         /*
1242          * cleanup and return
1243          */
1244         s = res->str;
1245         g_string_free (res, FALSE);
1246         return s;
1247 }
1248
1249 /**
1250  * Returns a stringifed representation of a field ref
1251  */
1252 char *
1253 get_fieldref_signature (MonoImage *m, int idx)
1254 {
1255         guint32 cols [MONO_MEMBERREF_SIZE];
1256         char *sig;
1257         char *full_sig;
1258
1259         mono_metadata_decode_row (&m->tables [MONO_TABLE_MEMBERREF],
1260                         idx - 1, cols, MONO_MEMBERREF_SIZE);
1261
1262         sig = get_field_signature (m, cols [MONO_MEMBERREF_SIGNATURE]);
1263         full_sig = g_strdup_printf ("%s %s::%s", sig,
1264                         get_memberref_parent (m, cols [MONO_MEMBERREF_CLASS]),
1265                         mono_metadata_string_heap (m, cols [MONO_MEMBERREF_NAME]));
1266         g_free (sig);
1267         
1268         return full_sig;
1269 }
1270
1271 /**
1272  * get_field:
1273  * @m: metadata context
1274  * @token: a FIELD_DEF token
1275  *
1276  * This routine has to locate the TypeDef that "owns" this Field.
1277  * Since there is no backpointer in the Field table, we have to scan
1278  * the TypeDef table and locate the actual "owner" of the field
1279  */
1280 char *
1281 get_field (MonoImage *m, guint32 token)
1282 {
1283         int idx = mono_metadata_token_index (token);
1284         guint32 cols [MONO_FIELD_SIZE];
1285         char *sig, *res, *type, *estype, *esname;
1286         guint32 type_idx;
1287
1288         /*
1289          * We can get here also with a MenberRef token (for a field
1290          * defined in another module/assembly, just like in get_method ()
1291          */
1292         if (mono_metadata_token_code (token) == MONO_TOKEN_MEMBER_REF) {
1293                 return get_fieldref_signature (m, idx);
1294         }
1295         g_assert (mono_metadata_token_code (token) == MONO_TOKEN_FIELD_DEF);
1296
1297         mono_metadata_decode_row (&m->tables [MONO_TABLE_FIELD], idx - 1, cols, MONO_FIELD_SIZE);
1298         sig = get_field_signature (m, cols [MONO_FIELD_SIGNATURE]);
1299
1300         /*
1301          * To locate the actual "container" for this field, we have to scan
1302          * the TypeDef table.  LAME!
1303          */
1304         type_idx = mono_metadata_typedef_from_field (m, idx);
1305
1306         type = get_typedef (m, type_idx);
1307         estype = get_escaped_name (type);
1308         esname = get_escaped_name (mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]));
1309         res = g_strdup_printf ("%s %s::%s",
1310                         sig, estype, esname);
1311
1312         g_free (type);
1313         g_free (sig);
1314         g_free (estype);
1315         g_free (esname);
1316
1317         return res;
1318 }
1319
1320 static char *
1321 get_memberref_parent (MonoImage *m, guint32 mrp_token)
1322 {
1323         /*
1324          * mrp_index is a MemberRefParent coded index
1325          */
1326         guint32 table = mrp_token & 7;
1327         guint32 idx = mrp_token >> 3;
1328
1329         switch (table){
1330         case 0: /* TypeDef */
1331                 return get_typedef (m, idx);
1332                 
1333         case 1: /* TypeRef */
1334                 return get_typeref (m, idx);
1335                 
1336         case 2: /* ModuleRef */
1337                 return g_strdup_printf ("TODO:MemberRefParent-ModuleRef");
1338                 
1339         case 3: /* MethodDef */
1340                 return g_strdup ("TODO:MethodDef");
1341                 
1342         case 4: /* TypeSpec */
1343                 return get_typespec (m, idx);
1344         }
1345         g_assert_not_reached ();
1346         return NULL;
1347 }
1348
1349 /**
1350  * get_method:
1351  * @m: metadata context
1352  * @token: a METHOD_DEF or MEMBER_REF token
1353  *
1354  * This routine has to locate the TypeDef that "owns" this Field.
1355  * Since there is no backpointer in the Field table, we have to scan
1356  * the TypeDef table and locate the actual "owner" of the field
1357  */
1358 char *
1359 get_method (MonoImage *m, guint32 token)
1360 {
1361         int idx = mono_metadata_token_index (token);
1362         guint32 member_cols [MONO_MEMBERREF_SIZE], method_cols [MONO_METHOD_SIZE];
1363         char *sig, *esname;
1364         const char *name;
1365
1366         MonoMethod *mh;
1367
1368         mh = mono_get_method (m, token, NULL);
1369         if (mh) {
1370                 esname = get_escaped_name (mh->name);
1371                 sig = dis_stringify_object_with_class (m, mh->klass);
1372                 if (show_tokens)
1373                         name = g_strdup_printf ("%s/*%08x*/::%s", sig, token, esname);
1374                 else
1375                         name = g_strdup_printf ("%s::%s", sig, esname);
1376                 g_free (sig);
1377                 g_free (esname);
1378         } else
1379                 name = NULL;
1380
1381         switch (mono_metadata_token_code (token)){
1382         case MONO_TOKEN_METHOD_DEF:
1383                 mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD], 
1384                                           idx - 1, method_cols, MONO_METHOD_SIZE);
1385
1386                 sig = get_methodref_signature (m, method_cols [MONO_METHOD_SIGNATURE], name);
1387                 break;
1388                 
1389         case MONO_TOKEN_MEMBER_REF: {
1390                 mono_metadata_decode_row (&m->tables [MONO_TABLE_MEMBERREF],
1391                                           idx - 1, member_cols, MONO_MEMBERREF_SIZE);
1392                 if (!name)
1393                         name = g_strdup_printf ("%s::%s",
1394                                         get_memberref_parent (m, member_cols [MONO_MEMBERREF_CLASS]),
1395                                         mono_metadata_string_heap (m, member_cols [MONO_MEMBERREF_NAME]));
1396                 sig = get_methodref_signature (
1397                         m, member_cols [MONO_MEMBERREF_SIGNATURE], name);
1398                 break;
1399         }
1400         case MONO_TOKEN_METHOD_SPEC: {
1401                 mono_metadata_decode_row (&m->tables [MONO_TABLE_METHODSPEC],
1402                                 idx - 1, member_cols, MONO_METHODSPEC_SIZE);
1403                 token = member_cols [MONO_METHODSPEC_METHOD];
1404                 sig = get_methodspec (m, idx, token, name);
1405                 break;
1406         }
1407
1408         default:
1409                 g_assert_not_reached ();
1410         }
1411
1412         if (show_tokens) {
1413                 char *retval = g_strdup_printf ("%s /* %08x */", sig, token);
1414                 g_free (sig);
1415                 return retval;
1416         } else
1417                 return sig;
1418 }
1419
1420 /**
1421  * get_methoddef
1422  * @m: metadata context
1423  * @idx: index into the method table
1424  *
1425  * Returns: A stringified version of the method signature.
1426  */
1427 char *
1428 get_methoddef (MonoImage *m, guint32 idx)
1429 {
1430         guint32 cols [MONO_METHOD_SIZE];
1431         char *sig;
1432         const char *name;
1433
1434         MonoMethod *mh;
1435
1436         mh = mono_get_method (m, MONO_TOKEN_METHOD_DEF | idx, NULL);
1437         if (mh) {
1438                 sig = dis_stringify_object_with_class (m, mh->klass);
1439                 name = g_strdup_printf ("%s::%s", sig, mh->name);
1440                 g_free (sig);
1441         } else
1442                 name = NULL;
1443         mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD], 
1444                         idx - 1, cols, MONO_METHOD_SIZE);
1445         sig = get_methodref_signature (m, cols [MONO_METHOD_SIGNATURE], name);
1446         
1447         return sig;
1448 }
1449
1450 char *
1451 get_method_type_param (MonoImage *m, guint32 blob_signature)
1452 {
1453         GString *res = g_string_new ("");
1454         const char *ptr = mono_metadata_blob_heap (m, blob_signature);
1455         int param_count;
1456         int i = 0;
1457         char *s;
1458         
1459         mono_metadata_decode_value (ptr, &ptr);
1460         ptr++;
1461         param_count = mono_metadata_decode_value (ptr, &ptr);
1462         
1463         g_string_append_c (res, '<');
1464         
1465         for (i = 0; i < param_count; i++){
1466                 char *param = NULL;
1467                 
1468                 ptr = get_param (m, ptr, &param);
1469                 g_string_append (res, param);
1470                 if (i+1 != param_count)
1471                         g_string_append (res, ", ");
1472                 g_free (param);
1473         }
1474         g_string_append_c (res, '>');
1475         
1476         s = res->str;
1477         g_string_free (res, FALSE);
1478         return s;
1479 }
1480
1481 /**
1482  * get_methodspec
1483  *
1484  * Returns: An allocated stringified version of the methodspec signature.
1485  */
1486
1487 char *
1488 get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name)
1489 {
1490         GString *res = g_string_new ("");
1491         guint32 member_cols [MONO_MEMBERREF_SIZE], method_cols [MONO_METHOD_SIZE];
1492         char *s, *type_param;
1493         const char *ptr;
1494         guint32 sig;
1495         int param_count, cconv, i, gen_count = 0;
1496
1497         switch (token & MONO_METHODDEFORREF_MASK) {
1498         case MONO_METHODDEFORREF_METHODDEF:
1499                 mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD], 
1500                                           (token >> MONO_METHODDEFORREF_BITS) - 1,
1501                                           method_cols, MONO_METHOD_SIZE);
1502                 sig = method_cols [MONO_METHOD_SIGNATURE];
1503                 break;
1504         case MONO_METHODDEFORREF_METHODREF:
1505                 mono_metadata_decode_row (&m->tables [MONO_TABLE_MEMBERREF], 
1506                                           (token >> MONO_METHODDEFORREF_BITS) - 1,
1507                                           member_cols, MONO_MEMBERREF_SIZE);
1508                 sig = member_cols [MONO_MEMBERREF_SIGNATURE];
1509                 break;
1510         default:
1511                 g_assert_not_reached ();
1512         }
1513
1514         ptr = mono_metadata_blob_heap (m, sig);
1515         mono_metadata_decode_value (ptr, &ptr);
1516
1517         if (*ptr & 0x20){
1518                 if (*ptr & 0x40)
1519                         g_string_append (res, "explicit-this ");
1520                 else
1521                         g_string_append (res, "instance "); /* has-this */
1522         }
1523
1524         if (*ptr & 0x10)
1525                 gen_count = 1;
1526         cconv = *ptr & 0x0f;
1527         ptr++;
1528         if (gen_count)
1529                 gen_count = mono_metadata_decode_value (ptr, &ptr);
1530         param_count = mono_metadata_decode_value (ptr, &ptr);
1531         if (cconv != 0xa) {
1532                 char *allocated_ret_type;
1533                 ptr = get_ret_type (m, ptr, &allocated_ret_type);
1534                 g_string_append (res, allocated_ret_type);
1535                 g_free (allocated_ret_type);
1536         }
1537
1538         if (fancy_name){
1539                 g_string_append_c (res, ' ');
1540                 g_string_append (res, fancy_name);
1541         }
1542
1543         mono_metadata_decode_row (&m->tables [MONO_TABLE_METHODSPEC],
1544                         idx - 1, member_cols, MONO_METHODSPEC_SIZE);
1545         token = member_cols [MONO_METHODSPEC_SIGNATURE];
1546         type_param = get_method_type_param (m, token);
1547         g_string_append (res, type_param);
1548         g_string_append (res, " (");
1549
1550         /*
1551          * methodspecs can not be varargs so we don't need to worry about that here
1552          */
1553          
1554         for (i = 0; i < param_count; i++){
1555                 char *param = NULL;
1556                 
1557                 ptr = get_param (m, ptr, &param);
1558                 g_string_append (res, param);
1559                 if (i+1 != param_count)
1560                         g_string_append (res, ", ");
1561                 g_free (param);
1562         }
1563         g_string_append (res, ")");
1564         
1565         /*
1566          * cleanup and return
1567          */
1568         s = res->str;
1569         g_string_free (res, FALSE);
1570         return s;
1571 }
1572
1573
1574 /**
1575  * get_constant:
1576  * @m: metadata context
1577  * @blob_index: index into the blob where the constant is stored
1578  *
1579  * Returns: An allocated value representing a stringified version of the
1580  * constant.
1581  */
1582 char *
1583 get_constant (MonoImage *m, MonoTypeEnum t, guint32 blob_index)
1584 {
1585         const char *ptr = mono_metadata_blob_heap (m, blob_index);
1586         int len;
1587         
1588         len = mono_metadata_decode_value (ptr, &ptr);
1589         
1590         switch (t){
1591         case MONO_TYPE_BOOLEAN:
1592                 return g_strdup_printf ("%s", *ptr ? "bool(true)" : "bool(false)");
1593                 
1594         case MONO_TYPE_CHAR:
1595                 return g_strdup_printf ("%c", *ptr); /* FIXME: unicode char */
1596                 
1597         case MONO_TYPE_U1:
1598         case MONO_TYPE_I1:
1599                 return g_strdup_printf ("int8(0x%02x)", (int) (*ptr));
1600                 break;
1601                 
1602         case MONO_TYPE_U2:
1603         case MONO_TYPE_I2:
1604                 return g_strdup_printf ("int16(0x%08x)", (int) read16 (ptr));
1605                 
1606         case MONO_TYPE_U4:
1607         case MONO_TYPE_I4:
1608                 return g_strdup_printf ("int32(%d)", read32 (ptr));
1609                 
1610         case MONO_TYPE_I8: {
1611                 guint32 low, high;
1612                 low = read32 (ptr);
1613                 high = read32 (ptr + 4);
1614                 return g_strdup_printf ("0x%08x%08x", high, low);
1615         }
1616         case MONO_TYPE_U8: {
1617                 guint32 low, high;
1618                 low = read32 (ptr);
1619                 high = read32 (ptr + 4);
1620                 return g_strdup_printf ("0x%08x%08x", high, low);
1621         }
1622         case MONO_TYPE_R4: {
1623                 float r;
1624                 readr4 (ptr, &r);
1625                 return g_strdup_printf ("%g", (double) r);
1626         }
1627         case MONO_TYPE_R8: {
1628                 double r;
1629                 readr8 (ptr, &r);
1630                 return g_strdup_printf ("%g", r);
1631         }
1632         case MONO_TYPE_STRING: {
1633                 int i, j, e;
1634                 char *res;
1635                 e = len = 0;
1636                 for (i = 0; !ptr [i+1]; i += 2){
1637                         len++;
1638                         switch (ptr [i]) {
1639                         case '"':
1640                         case '\\':
1641                         case '\n': /* add more */
1642                                 e++;
1643                         }
1644                 }
1645                 res = g_malloc (len + e + 3);
1646                 j = 1;
1647                 res [0] = '"';
1648
1649                 for (i = 0; i < len; i += 2){
1650                         switch(ptr[i]) {
1651                         case '"': 
1652                                 res[j++] = '\\';
1653                                 res[j++] = '"';
1654                         case '\\': 
1655                                 res[j++] = '\\';
1656                                 res[j++] = '\\';
1657                         case '\n':
1658                                 res[j++] = '\\';
1659                                 res[j++] = 'n';
1660                                 break;
1661                         default:
1662                                 res[j++] = isprint (ptr [i]) ? ptr [i] : '.';
1663                                 break;
1664                         }
1665                 }
1666                 res[j++] = '"';
1667                 res[j] = 0;
1668                 return res;
1669         }
1670                 
1671         case MONO_TYPE_CLASS:
1672                 return g_strdup ("CLASS CONSTANT.  MUST BE ZERO");
1673                 
1674         default:
1675                 g_error ("Unknown MONO_TYPE (%d) on constant at Blob index (0x%08x)\n",
1676                          (int) *ptr, blob_index);
1677                 return g_strdup_printf ("Unknown");
1678         }
1679
1680 }
1681
1682 /**
1683  * get_token:
1684  * @m: metadata context
1685  * @token: token that we want to decode.
1686  *
1687  * Returns: An allocated value representing a stringified version of the
1688  * constant.
1689  */
1690 char *
1691 get_token (MonoImage *m, guint32 token)
1692 {
1693         char *temp, *result;
1694         guint32 idx = mono_metadata_token_index (token);
1695
1696         switch (mono_metadata_token_code (token)){
1697         case MONO_TOKEN_FIELD_DEF:
1698                 temp = get_field (m, token);
1699                 result = g_strdup_printf ("field %s", temp);
1700                 g_free (temp);
1701                 return result;
1702         case MONO_TOKEN_TYPE_DEF:
1703                 return get_typedef (m, idx);
1704         case MONO_TOKEN_TYPE_REF:
1705                 return get_typeref (m, idx);
1706         case MONO_TOKEN_TYPE_SPEC:
1707                 return get_typespec (m, idx);
1708         default:                
1709                 g_error ("Do not know how to decode tokens of type 0x%08x", token);
1710         }
1711
1712         g_assert_not_reached ();
1713         return g_strdup ("ERROR");
1714 }
1715
1716 /**
1717  * get_token_type:
1718  * @m: metadata context
1719  * @token: the token can belong to any of the following tables:
1720  * MONO_TOKEN_TYPE_REF, MONO_TOKEN_TYPE_DEF, MONO_TOKEN_TYPE_SPEC
1721  *
1722  * Returns: a stringified version of the MethodDef or MethodRef or TypeSpecn
1723  * at (token & 0xffffff) 
1724  */
1725 char *
1726 get_token_type (MonoImage *m, guint32 token)
1727 {
1728         char *temp = NULL, *s = NULL;
1729         int idx;
1730
1731         idx = mono_metadata_token_index (token);
1732         
1733         switch (mono_metadata_token_code (token)){
1734         case MONO_TOKEN_TYPE_DEF:
1735                 temp = get_typedef (m, idx);
1736                 s = g_strdup_printf ("%s", temp);
1737                 break;
1738                 
1739         case MONO_TOKEN_TYPE_REF: 
1740                 temp = get_typeref (m, idx);
1741                 s = g_strdup_printf ("%s", temp);
1742                 break;
1743                 
1744         case MONO_TOKEN_TYPE_SPEC:
1745                 s = get_typespec (m, idx);
1746                 break;
1747
1748         default:
1749                 g_error ("Unhandled encoding for token 0x%08x", token);
1750
1751         }
1752         
1753         if (temp)
1754                 g_free (temp);
1755
1756         return s;
1757 }
1758
1759 char *
1760 get_guid (MonoImage *m, guint32 guid_index)
1761 {
1762         const unsigned char *guid;
1763         char *result;
1764
1765         guid = mono_metadata_guid_heap (m, guid_index);
1766
1767         result = g_strdup_printf ("{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}", 
1768                         guid [3], guid [2], guid [1], guid [0], guid [5], guid [4], guid [7], guid [6],
1769                         guid [8], guid [9], guid [10], guid [11], guid [12], guid [13], guid [14], guid [15]);
1770         return result;
1771 }
1772
1773 GList *
1774 dis_get_custom_attrs (MonoImage *m, guint32 token)
1775 {
1776         GList *list = NULL;
1777         guint32 idx, i, len, mtoken;
1778         guint32 cols [MONO_CUSTOM_ATTR_SIZE];
1779         MonoTableInfo *ca;
1780         char *method;
1781         GString *attr;
1782         const char *val;
1783
1784         idx = mono_metadata_token_index (token);
1785         idx <<= MONO_CUSTOM_ATTR_BITS;
1786         
1787         switch (mono_metadata_token_table (token)) {
1788         case MONO_TABLE_TYPEDEF:
1789                 idx |= MONO_CUSTOM_ATTR_TYPEDEF;
1790                 break;
1791         case MONO_TABLE_ASSEMBLY:
1792                 idx |= MONO_CUSTOM_ATTR_ASSEMBLY;
1793                 break;
1794         case MONO_TABLE_MODULE:
1795                 idx |= MONO_CUSTOM_ATTR_MODULE;
1796                 break;
1797         case MONO_TABLE_PROPERTY:
1798                 idx |= MONO_CUSTOM_ATTR_PROPERTY;
1799                 break;
1800         case MONO_TABLE_EVENT:
1801                 idx |= MONO_CUSTOM_ATTR_EVENT;
1802                 break;
1803         case MONO_TABLE_FIELD:
1804                 idx |= MONO_CUSTOM_ATTR_FIELDDEF;
1805                 break;
1806         case MONO_TABLE_METHOD:
1807                 idx |= MONO_CUSTOM_ATTR_METHODDEF;
1808                 break;
1809         case MONO_TABLE_PARAM:
1810                 idx |= MONO_CUSTOM_ATTR_PARAMDEF;
1811                 break;
1812         default:
1813                 g_print ("Missing custom attr get support for token 0x%08x\n", token);
1814                 return NULL;
1815         }
1816
1817         ca = &m->tables [MONO_TABLE_CUSTOMATTRIBUTE];
1818         /* the table is not sorted */
1819         for (i = 0; i < ca->rows; ++i) {
1820                 char *dump;
1821                 mono_metadata_decode_row (ca, i, cols, MONO_CUSTOM_ATTR_SIZE);
1822                 if (cols [MONO_CUSTOM_ATTR_PARENT] != idx)
1823                         continue;
1824                 mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> MONO_CUSTOM_ATTR_TYPE_BITS;
1825                 switch (cols [MONO_CUSTOM_ATTR_TYPE] & MONO_CUSTOM_ATTR_TYPE_MASK) {
1826                 case MONO_CUSTOM_ATTR_TYPE_METHODDEF:
1827                         mtoken |= MONO_TOKEN_METHOD_DEF;
1828                         break;
1829                 case MONO_CUSTOM_ATTR_TYPE_MEMBERREF:
1830                         mtoken |= MONO_TOKEN_MEMBER_REF;
1831                         break;
1832                 default:
1833                         g_error ("Unknown table for custom attr type %08x", cols [MONO_CUSTOM_ATTR_TYPE]);
1834                         break;
1835                 }
1836                 method = get_method (m, mtoken);
1837                 val = mono_metadata_blob_heap (m, cols [MONO_CUSTOM_ATTR_VALUE]);
1838                 len = mono_metadata_decode_value (val, &val);
1839                 attr = g_string_new (".custom ");
1840                 dump = data_dump (val, len, "\t\t");
1841                 g_string_sprintfa (attr, "%s = %s", method, dump);
1842                 g_free (dump);
1843                 list = g_list_append (list, attr->str);
1844                 g_string_free (attr, FALSE);
1845                 g_free (method);
1846         }
1847         return list;
1848 }
1849
1850 char*
1851 get_marshal_info (MonoImage *m, const char *blob) {
1852         int len, size = 0;
1853
1854         len = mono_metadata_decode_blob_size (blob, &blob);
1855
1856         switch (*blob) {
1857         case MONO_NATIVE_BOOLEAN:
1858                 return g_strdup ("bool");
1859         case MONO_NATIVE_I1:
1860                 return g_strdup ("int8");
1861         case MONO_NATIVE_U1:
1862                 return g_strdup ("unsigned int8");
1863         case MONO_NATIVE_I2:
1864                 return g_strdup ("int16");
1865         case MONO_NATIVE_U2:
1866                 return g_strdup ("unsigned int16");
1867         case MONO_NATIVE_I4:
1868                 return g_strdup ("int32");
1869         case MONO_NATIVE_U4:
1870                 return g_strdup ("unsigned int32");
1871         case MONO_NATIVE_I8:
1872                 return g_strdup ("int64");
1873         case MONO_NATIVE_U8:
1874                 return g_strdup ("unsigned int64");
1875         case MONO_NATIVE_R4:
1876                 return g_strdup ("float32");
1877         case MONO_NATIVE_R8:
1878                 return g_strdup ("float64");
1879         case MONO_NATIVE_CURRENCY:
1880                 return g_strdup ("currency");
1881         case MONO_NATIVE_BSTR:
1882                 return g_strdup ("bstr");
1883         case MONO_NATIVE_LPSTR:
1884                 return g_strdup ("lpstr");
1885         case MONO_NATIVE_LPWSTR:
1886                 return g_strdup ("lpwstr");
1887         case MONO_NATIVE_LPTSTR:
1888                 return g_strdup ("lptstr");
1889         case MONO_NATIVE_BYVALTSTR:
1890                 size = mono_metadata_decode_value (blob + 1, &blob);
1891                 return g_strdup_printf ("fixed sysstring [%d]", size);
1892         case MONO_NATIVE_IUNKNOWN:
1893                 return g_strdup ("iunknown");
1894         case MONO_NATIVE_IDISPATCH:
1895                 return g_strdup ("idispatch");
1896         case MONO_NATIVE_STRUCT:
1897                 return g_strdup ("struct");
1898         case MONO_NATIVE_INTERFACE:
1899                 return g_strdup ("interface");
1900         case MONO_NATIVE_SAFEARRAY:
1901                 return g_strdup ("safearray");
1902         case MONO_NATIVE_BYVALARRAY:
1903                 size = mono_metadata_decode_value (blob + 1, &blob);
1904                 return g_strdup_printf ("fixed array [%d]", size);
1905         case MONO_NATIVE_INT:
1906                 return g_strdup ("int");
1907         case MONO_NATIVE_UINT:
1908                 return g_strdup ("unsigned int");
1909         case MONO_NATIVE_VBBYREFSTR:
1910                 return g_strdup ("vbbyrefstr");
1911         case MONO_NATIVE_ANSIBSTR:
1912                 return g_strdup ("ansi bstr");
1913         case MONO_NATIVE_TBSTR:
1914                 return g_strdup ("tbstr");
1915         case MONO_NATIVE_VARIANTBOOL:
1916                 return g_strdup ("variant bool");
1917         case MONO_NATIVE_FUNC:
1918                 return g_strdup ("method");
1919         case MONO_NATIVE_ASANY:
1920                 return g_strdup ("as any");
1921         case MONO_NATIVE_LPARRAY:
1922                 return g_strdup ("[]");
1923         case MONO_NATIVE_LPSTRUCT:
1924                 return g_strdup ("lpstruct");
1925         case MONO_NATIVE_CUSTOM:
1926                 return g_strdup ("custom");
1927         case MONO_NATIVE_ERROR:
1928                 return g_strdup ("error");
1929         default:
1930                 return g_strdup ("unknown");
1931         }
1932 }
1933
1934 void
1935 init_key_table (void)
1936 {
1937         key_table = g_hash_table_new (g_str_hash, g_str_equal);
1938
1939         /* auto generated */
1940         g_hash_table_insert (key_table, (char *) "abstract", GINT_TO_POINTER (TRUE));
1941         g_hash_table_insert (key_table, (char *) "add", GINT_TO_POINTER (TRUE));
1942         g_hash_table_insert (key_table, (char *) "add.ovf", GINT_TO_POINTER (TRUE));
1943         g_hash_table_insert (key_table, (char *) "add.ovf.un", GINT_TO_POINTER (TRUE));
1944         g_hash_table_insert (key_table, (char *) "algorithm", GINT_TO_POINTER (TRUE));
1945         g_hash_table_insert (key_table, (char *) "alignment", GINT_TO_POINTER (TRUE));
1946         g_hash_table_insert (key_table, (char *) "and", GINT_TO_POINTER (TRUE));
1947         g_hash_table_insert (key_table, (char *) "ansi", GINT_TO_POINTER (TRUE));
1948         g_hash_table_insert (key_table, (char *) "any", GINT_TO_POINTER (TRUE));
1949         g_hash_table_insert (key_table, (char *) "arglist", GINT_TO_POINTER (TRUE));
1950         g_hash_table_insert (key_table, (char *) "array", GINT_TO_POINTER (TRUE));
1951         g_hash_table_insert (key_table, (char *) "as", GINT_TO_POINTER (TRUE));
1952         g_hash_table_insert (key_table, (char *) "assembly", GINT_TO_POINTER (TRUE));
1953         g_hash_table_insert (key_table, (char *) "assert", GINT_TO_POINTER (TRUE));
1954         g_hash_table_insert (key_table, (char *) "at", GINT_TO_POINTER (TRUE));
1955         g_hash_table_insert (key_table, (char *) "auto", GINT_TO_POINTER (TRUE));
1956         g_hash_table_insert (key_table, (char *) "autochar", GINT_TO_POINTER (TRUE));
1957         g_hash_table_insert (key_table, (char *) "beforefieldinit", GINT_TO_POINTER (TRUE));
1958         g_hash_table_insert (key_table, (char *) "beq", GINT_TO_POINTER (TRUE));
1959         g_hash_table_insert (key_table, (char *) "beq.s", GINT_TO_POINTER (TRUE));
1960         g_hash_table_insert (key_table, (char *) "bge", GINT_TO_POINTER (TRUE));
1961         g_hash_table_insert (key_table, (char *) "bge.s", GINT_TO_POINTER (TRUE));
1962         g_hash_table_insert (key_table, (char *) "bge.un", GINT_TO_POINTER (TRUE));
1963         g_hash_table_insert (key_table, (char *) "bge.un.s", GINT_TO_POINTER (TRUE));
1964         g_hash_table_insert (key_table, (char *) "bgt", GINT_TO_POINTER (TRUE));
1965         g_hash_table_insert (key_table, (char *) "bgt.s", GINT_TO_POINTER (TRUE));
1966         g_hash_table_insert (key_table, (char *) "bgt.un", GINT_TO_POINTER (TRUE));
1967         g_hash_table_insert (key_table, (char *) "9", GINT_TO_POINTER (TRUE));
1968         g_hash_table_insert (key_table, (char *) "bgt.un.s", GINT_TO_POINTER (TRUE));
1969         g_hash_table_insert (key_table, (char *) "ble", GINT_TO_POINTER (TRUE));
1970         g_hash_table_insert (key_table, (char *) "ble.s", GINT_TO_POINTER (TRUE));
1971         g_hash_table_insert (key_table, (char *) "ble.un", GINT_TO_POINTER (TRUE));
1972         g_hash_table_insert (key_table, (char *) "ble.un.s", GINT_TO_POINTER (TRUE));
1973         g_hash_table_insert (key_table, (char *) "blob", GINT_TO_POINTER (TRUE));
1974         g_hash_table_insert (key_table, (char *) "blob_object", GINT_TO_POINTER (TRUE));
1975         g_hash_table_insert (key_table, (char *) "blt", GINT_TO_POINTER (TRUE));
1976         g_hash_table_insert (key_table, (char *) "blt.s", GINT_TO_POINTER (TRUE));
1977         g_hash_table_insert (key_table, (char *) "blt.un", GINT_TO_POINTER (TRUE));
1978         g_hash_table_insert (key_table, (char *) "blt.un.s", GINT_TO_POINTER (TRUE));
1979         g_hash_table_insert (key_table, (char *) "bne.un", GINT_TO_POINTER (TRUE));
1980         g_hash_table_insert (key_table, (char *) "bne.un.s", GINT_TO_POINTER (TRUE));
1981         g_hash_table_insert (key_table, (char *) "bool", GINT_TO_POINTER (TRUE));
1982         g_hash_table_insert (key_table, (char *) "box", GINT_TO_POINTER (TRUE));
1983         g_hash_table_insert (key_table, (char *) "br", GINT_TO_POINTER (TRUE));
1984         g_hash_table_insert (key_table, (char *) "br.s", GINT_TO_POINTER (TRUE));
1985         g_hash_table_insert (key_table, (char *) "break", GINT_TO_POINTER (TRUE));
1986         g_hash_table_insert (key_table, (char *) "brfalse", GINT_TO_POINTER (TRUE));
1987         g_hash_table_insert (key_table, (char *) "brfalse.s", GINT_TO_POINTER (TRUE));
1988         g_hash_table_insert (key_table, (char *) "brinst", GINT_TO_POINTER (TRUE));
1989         g_hash_table_insert (key_table, (char *) "brinst.s", GINT_TO_POINTER (TRUE));
1990         g_hash_table_insert (key_table, (char *) "brnull", GINT_TO_POINTER (TRUE));
1991         g_hash_table_insert (key_table, (char *) "brnull.s", GINT_TO_POINTER (TRUE));
1992         g_hash_table_insert (key_table, (char *) "brtrue", GINT_TO_POINTER (TRUE));
1993         g_hash_table_insert (key_table, (char *) "brtrue.s", GINT_TO_POINTER (TRUE));
1994         g_hash_table_insert (key_table, (char *) "brzero", GINT_TO_POINTER (TRUE));
1995         g_hash_table_insert (key_table, (char *) "brzero.s", GINT_TO_POINTER (TRUE));
1996         g_hash_table_insert (key_table, (char *) "bstr", GINT_TO_POINTER (TRUE));
1997         g_hash_table_insert (key_table, (char *) "bytearray", GINT_TO_POINTER (TRUE));
1998         g_hash_table_insert (key_table, (char *) "byvalstr", GINT_TO_POINTER (TRUE));
1999         g_hash_table_insert (key_table, (char *) "call", GINT_TO_POINTER (TRUE));
2000         g_hash_table_insert (key_table, (char *) "calli", GINT_TO_POINTER (TRUE));
2001         g_hash_table_insert (key_table, (char *) "callmostderived", GINT_TO_POINTER (TRUE));
2002         g_hash_table_insert (key_table, (char *) "callvirt", GINT_TO_POINTER (TRUE));
2003         g_hash_table_insert (key_table, (char *) "carray", GINT_TO_POINTER (TRUE));
2004         g_hash_table_insert (key_table, (char *) "castclass", GINT_TO_POINTER (TRUE));
2005         g_hash_table_insert (key_table, (char *) "catch", GINT_TO_POINTER (TRUE));
2006         g_hash_table_insert (key_table, (char *) "cdecl", GINT_TO_POINTER (TRUE));
2007         g_hash_table_insert (key_table, (char *) "ceq", GINT_TO_POINTER (TRUE));
2008         g_hash_table_insert (key_table, (char *) "cf", GINT_TO_POINTER (TRUE));
2009         g_hash_table_insert (key_table, (char *) "cgt", GINT_TO_POINTER (TRUE));
2010         g_hash_table_insert (key_table, (char *) "cgt.un", GINT_TO_POINTER (TRUE));
2011         g_hash_table_insert (key_table, (char *) "char", GINT_TO_POINTER (TRUE));
2012         g_hash_table_insert (key_table, (char *) "cil", GINT_TO_POINTER (TRUE));
2013         g_hash_table_insert (key_table, (char *) "ckfinite", GINT_TO_POINTER (TRUE));
2014         g_hash_table_insert (key_table, (char *) "class", GINT_TO_POINTER (TRUE));
2015         g_hash_table_insert (key_table, (char *) "clsid", GINT_TO_POINTER (TRUE));
2016         g_hash_table_insert (key_table, (char *) "clt", GINT_TO_POINTER (TRUE));
2017         g_hash_table_insert (key_table, (char *) "clt.un", GINT_TO_POINTER (TRUE));
2018         g_hash_table_insert (key_table, (char *) "const", GINT_TO_POINTER (TRUE));
2019         g_hash_table_insert (key_table, (char *) "conv.i", GINT_TO_POINTER (TRUE));
2020         g_hash_table_insert (key_table, (char *) "conv.i1", GINT_TO_POINTER (TRUE));
2021         g_hash_table_insert (key_table, (char *) "conv.i2", GINT_TO_POINTER (TRUE));
2022         g_hash_table_insert (key_table, (char *) "conv.i4", GINT_TO_POINTER (TRUE));
2023         g_hash_table_insert (key_table, (char *) "conv.i8", GINT_TO_POINTER (TRUE));
2024         g_hash_table_insert (key_table, (char *) "conv.ovf.i", GINT_TO_POINTER (TRUE));
2025         g_hash_table_insert (key_table, (char *) "conv.ovf.i.un", GINT_TO_POINTER (TRUE));
2026         g_hash_table_insert (key_table, (char *) "conv.ovf.i1", GINT_TO_POINTER (TRUE));
2027         g_hash_table_insert (key_table, (char *) "conv.ovf.i1.un", GINT_TO_POINTER (TRUE));
2028         g_hash_table_insert (key_table, (char *) "conv.ovf.i2", GINT_TO_POINTER (TRUE));
2029         g_hash_table_insert (key_table, (char *) "conv.ovf.i2.un", GINT_TO_POINTER (TRUE));
2030         g_hash_table_insert (key_table, (char *) "conv.ovf.i4", GINT_TO_POINTER (TRUE));
2031         g_hash_table_insert (key_table, (char *) "conv.ovf.i4.un", GINT_TO_POINTER (TRUE));
2032         g_hash_table_insert (key_table, (char *) "conv.ovf.i8", GINT_TO_POINTER (TRUE));
2033         g_hash_table_insert (key_table, (char *) "conv.ovf.i8.un", GINT_TO_POINTER (TRUE));
2034         g_hash_table_insert (key_table, (char *) "conv.ovf.u", GINT_TO_POINTER (TRUE));
2035         g_hash_table_insert (key_table, (char *) "conv.ovf.u.un", GINT_TO_POINTER (TRUE));
2036         g_hash_table_insert (key_table, (char *) "conv.ovf.u1", GINT_TO_POINTER (TRUE));
2037         g_hash_table_insert (key_table, (char *) "conv.ovf.u1.un", GINT_TO_POINTER (TRUE));
2038         g_hash_table_insert (key_table, (char *) "conv.ovf.u2", GINT_TO_POINTER (TRUE));
2039         g_hash_table_insert (key_table, (char *) "conv.ovf.u2.un", GINT_TO_POINTER (TRUE));
2040         g_hash_table_insert (key_table, (char *) "conv.ovf.u4", GINT_TO_POINTER (TRUE));
2041         g_hash_table_insert (key_table, (char *) "conv.ovf.u4.un", GINT_TO_POINTER (TRUE));
2042         g_hash_table_insert (key_table, (char *) "conv.ovf.u8", GINT_TO_POINTER (TRUE));
2043         g_hash_table_insert (key_table, (char *) "conv.ovf.u8.un", GINT_TO_POINTER (TRUE));
2044         g_hash_table_insert (key_table, (char *) "conv.r.un", GINT_TO_POINTER (TRUE));
2045         g_hash_table_insert (key_table, (char *) "conv.r4", GINT_TO_POINTER (TRUE));
2046         g_hash_table_insert (key_table, (char *) "conv.r8", GINT_TO_POINTER (TRUE));
2047         g_hash_table_insert (key_table, (char *) "conv.u", GINT_TO_POINTER (TRUE));
2048         g_hash_table_insert (key_table, (char *) "conv.u1", GINT_TO_POINTER (TRUE));
2049         g_hash_table_insert (key_table, (char *) "conv.u2", GINT_TO_POINTER (TRUE));
2050         g_hash_table_insert (key_table, (char *) "conv.u4", GINT_TO_POINTER (TRUE));
2051         g_hash_table_insert (key_table, (char *) "conv.u8", GINT_TO_POINTER (TRUE));
2052         g_hash_table_insert (key_table, (char *) "cpblk", GINT_TO_POINTER (TRUE));
2053         g_hash_table_insert (key_table, (char *) "cpobj", GINT_TO_POINTER (TRUE));
2054         g_hash_table_insert (key_table, (char *) "currency", GINT_TO_POINTER (TRUE));
2055         g_hash_table_insert (key_table, (char *) "custom", GINT_TO_POINTER (TRUE));
2056         g_hash_table_insert (key_table, (char *) "date", GINT_TO_POINTER (TRUE));
2057         g_hash_table_insert (key_table, (char *) "decimal", GINT_TO_POINTER (TRUE));
2058         g_hash_table_insert (key_table, (char *) "default", GINT_TO_POINTER (TRUE));
2059         g_hash_table_insert (key_table, (char *) "default", GINT_TO_POINTER (TRUE));
2060         g_hash_table_insert (key_table, (char *) "demand", GINT_TO_POINTER (TRUE));
2061         g_hash_table_insert (key_table, (char *) "deny", GINT_TO_POINTER (TRUE));
2062         g_hash_table_insert (key_table, (char *) "div", GINT_TO_POINTER (TRUE));
2063         g_hash_table_insert (key_table, (char *) "div.un", GINT_TO_POINTER (TRUE));
2064         g_hash_table_insert (key_table, (char *) "dup", GINT_TO_POINTER (TRUE));
2065         g_hash_table_insert (key_table, (char *) "endfault", GINT_TO_POINTER (TRUE));
2066         g_hash_table_insert (key_table, (char *) "endfilter", GINT_TO_POINTER (TRUE));
2067         g_hash_table_insert (key_table, (char *) "endfinally", GINT_TO_POINTER (TRUE));
2068         g_hash_table_insert (key_table, (char *) "endmac", GINT_TO_POINTER (TRUE));
2069         g_hash_table_insert (key_table, (char *) "enum", GINT_TO_POINTER (TRUE));
2070         g_hash_table_insert (key_table, (char *) "error", GINT_TO_POINTER (TRUE));
2071         g_hash_table_insert (key_table, (char *) "explicit", GINT_TO_POINTER (TRUE));
2072         g_hash_table_insert (key_table, (char *) "extends", GINT_TO_POINTER (TRUE));
2073         g_hash_table_insert (key_table, (char *) "extern", GINT_TO_POINTER (TRUE));
2074         g_hash_table_insert (key_table, (char *) "false", GINT_TO_POINTER (TRUE));
2075         g_hash_table_insert (key_table, (char *) "famandassem", GINT_TO_POINTER (TRUE));
2076         g_hash_table_insert (key_table, (char *) "family", GINT_TO_POINTER (TRUE));
2077         g_hash_table_insert (key_table, (char *) "famorassem", GINT_TO_POINTER (TRUE));
2078         g_hash_table_insert (key_table, (char *) "fastcall", GINT_TO_POINTER (TRUE));
2079         g_hash_table_insert (key_table, (char *) "fastcall", GINT_TO_POINTER (TRUE));
2080         g_hash_table_insert (key_table, (char *) "fault", GINT_TO_POINTER (TRUE));
2081         g_hash_table_insert (key_table, (char *) "field", GINT_TO_POINTER (TRUE));
2082         g_hash_table_insert (key_table, (char *) "filetime", GINT_TO_POINTER (TRUE));
2083         g_hash_table_insert (key_table, (char *) "filter", GINT_TO_POINTER (TRUE));
2084         g_hash_table_insert (key_table, (char *) "final", GINT_TO_POINTER (TRUE));
2085         g_hash_table_insert (key_table, (char *) "finally", GINT_TO_POINTER (TRUE));
2086         g_hash_table_insert (key_table, (char *) "fixed", GINT_TO_POINTER (TRUE));
2087         g_hash_table_insert (key_table, (char *) "float", GINT_TO_POINTER (TRUE));
2088         g_hash_table_insert (key_table, (char *) "float32", GINT_TO_POINTER (TRUE));
2089         g_hash_table_insert (key_table, (char *) "float64", GINT_TO_POINTER (TRUE));
2090         g_hash_table_insert (key_table, (char *) "forwardref", GINT_TO_POINTER (TRUE));
2091         g_hash_table_insert (key_table, (char *) "fromunmanaged", GINT_TO_POINTER (TRUE));
2092         g_hash_table_insert (key_table, (char *) "handler", GINT_TO_POINTER (TRUE));
2093         g_hash_table_insert (key_table, (char *) "hidebysig", GINT_TO_POINTER (TRUE));
2094         g_hash_table_insert (key_table, (char *) "hresult", GINT_TO_POINTER (TRUE));
2095         g_hash_table_insert (key_table, (char *) "idispatch", GINT_TO_POINTER (TRUE));
2096         g_hash_table_insert (key_table, (char *) "il", GINT_TO_POINTER (TRUE));
2097         g_hash_table_insert (key_table, (char *) "illegal", GINT_TO_POINTER (TRUE));
2098         g_hash_table_insert (key_table, (char *) "implements", GINT_TO_POINTER (TRUE));
2099         g_hash_table_insert (key_table, (char *) "implicitcom", GINT_TO_POINTER (TRUE));
2100         g_hash_table_insert (key_table, (char *) "implicitres", GINT_TO_POINTER (TRUE));
2101         g_hash_table_insert (key_table, (char *) "import", GINT_TO_POINTER (TRUE));
2102         g_hash_table_insert (key_table, (char *) "in", GINT_TO_POINTER (TRUE));
2103         g_hash_table_insert (key_table, (char *) "inheritcheck", GINT_TO_POINTER (TRUE));
2104         g_hash_table_insert (key_table, (char *) "init", GINT_TO_POINTER (TRUE));
2105         g_hash_table_insert (key_table, (char *) "initblk", GINT_TO_POINTER (TRUE));
2106         g_hash_table_insert (key_table, (char *) "initobj", GINT_TO_POINTER (TRUE));
2107         g_hash_table_insert (key_table, (char *) "initonly", GINT_TO_POINTER (TRUE));
2108         g_hash_table_insert (key_table, (char *) "instance", GINT_TO_POINTER (TRUE));
2109         g_hash_table_insert (key_table, (char *) "int", GINT_TO_POINTER (TRUE));
2110         g_hash_table_insert (key_table, (char *) "int16", GINT_TO_POINTER (TRUE));
2111         g_hash_table_insert (key_table, (char *) "int32", GINT_TO_POINTER (TRUE));
2112         g_hash_table_insert (key_table, (char *) "int64", GINT_TO_POINTER (TRUE));
2113         g_hash_table_insert (key_table, (char *) "int8", GINT_TO_POINTER (TRUE));
2114         g_hash_table_insert (key_table, (char *) "interface", GINT_TO_POINTER (TRUE));
2115         g_hash_table_insert (key_table, (char *) "internalcall", GINT_TO_POINTER (TRUE));
2116         g_hash_table_insert (key_table, (char *) "isinst", GINT_TO_POINTER (TRUE));
2117         g_hash_table_insert (key_table, (char *) "iunknown", GINT_TO_POINTER (TRUE));
2118         g_hash_table_insert (key_table, (char *) "jmp", GINT_TO_POINTER (TRUE));
2119         g_hash_table_insert (key_table, (char *) "lasterr", GINT_TO_POINTER (TRUE));
2120         g_hash_table_insert (key_table, (char *) "lcid", GINT_TO_POINTER (TRUE));
2121         g_hash_table_insert (key_table, (char *) "ldarg", GINT_TO_POINTER (TRUE));
2122         g_hash_table_insert (key_table, (char *) "ldarg.0", GINT_TO_POINTER (TRUE));
2123         g_hash_table_insert (key_table, (char *) "ldarg.1", GINT_TO_POINTER (TRUE));
2124         g_hash_table_insert (key_table, (char *) "ldarg.2", GINT_TO_POINTER (TRUE));
2125         g_hash_table_insert (key_table, (char *) "ldarg.3", GINT_TO_POINTER (TRUE));
2126         g_hash_table_insert (key_table, (char *) "ldarg.s", GINT_TO_POINTER (TRUE));
2127         g_hash_table_insert (key_table, (char *) "ldarga", GINT_TO_POINTER (TRUE));
2128         g_hash_table_insert (key_table, (char *) "ldarga.s", GINT_TO_POINTER (TRUE));
2129         g_hash_table_insert (key_table, (char *) "ldc.i4", GINT_TO_POINTER (TRUE));
2130         g_hash_table_insert (key_table, (char *) "ldc.i4.0", GINT_TO_POINTER (TRUE));
2131         g_hash_table_insert (key_table, (char *) "ldc.i4.1", GINT_TO_POINTER (TRUE));
2132         g_hash_table_insert (key_table, (char *) "ldc.i4.2", GINT_TO_POINTER (TRUE));
2133         g_hash_table_insert (key_table, (char *) "ldc.i4.3", GINT_TO_POINTER (TRUE));
2134         g_hash_table_insert (key_table, (char *) "ldc.i4.4", GINT_TO_POINTER (TRUE));
2135         g_hash_table_insert (key_table, (char *) "ldc.i4.5", GINT_TO_POINTER (TRUE));
2136         g_hash_table_insert (key_table, (char *) "ldc.i4.6", GINT_TO_POINTER (TRUE));
2137         g_hash_table_insert (key_table, (char *) "ldc.i4.7", GINT_TO_POINTER (TRUE));
2138         g_hash_table_insert (key_table, (char *) "ldc.i4.8", GINT_TO_POINTER (TRUE));
2139         g_hash_table_insert (key_table, (char *) "ldc.i4.M1", GINT_TO_POINTER (TRUE));
2140         g_hash_table_insert (key_table, (char *) "ldc.i4.m1", GINT_TO_POINTER (TRUE));
2141         g_hash_table_insert (key_table, (char *) "ldc.i4.s", GINT_TO_POINTER (TRUE));
2142         g_hash_table_insert (key_table, (char *) "ldc.i8", GINT_TO_POINTER (TRUE));
2143         g_hash_table_insert (key_table, (char *) "ldc.r4", GINT_TO_POINTER (TRUE));
2144         g_hash_table_insert (key_table, (char *) "ldc.r8", GINT_TO_POINTER (TRUE));
2145         g_hash_table_insert (key_table, (char *) "ldelem.i", GINT_TO_POINTER (TRUE));
2146         g_hash_table_insert (key_table, (char *) "ldelem.i1", GINT_TO_POINTER (TRUE));
2147         g_hash_table_insert (key_table, (char *) "ldelem.i2", GINT_TO_POINTER (TRUE));
2148         g_hash_table_insert (key_table, (char *) "ldelem.i4", GINT_TO_POINTER (TRUE));
2149         g_hash_table_insert (key_table, (char *) "ldelem.i8", GINT_TO_POINTER (TRUE));
2150         g_hash_table_insert (key_table, (char *) "ldelem.r4", GINT_TO_POINTER (TRUE));
2151         g_hash_table_insert (key_table, (char *) "ldelem.r8", GINT_TO_POINTER (TRUE));
2152         g_hash_table_insert (key_table, (char *) "ldelem.ref", GINT_TO_POINTER (TRUE));
2153         g_hash_table_insert (key_table, (char *) "ldelem.u1", GINT_TO_POINTER (TRUE));
2154         g_hash_table_insert (key_table, (char *) "ldelem.u2", GINT_TO_POINTER (TRUE));
2155         g_hash_table_insert (key_table, (char *) "ldelem.u4", GINT_TO_POINTER (TRUE));
2156         g_hash_table_insert (key_table, (char *) "ldelem.u8", GINT_TO_POINTER (TRUE));
2157         g_hash_table_insert (key_table, (char *) "ldelema", GINT_TO_POINTER (TRUE));
2158         g_hash_table_insert (key_table, (char *) "ldfld", GINT_TO_POINTER (TRUE));
2159         g_hash_table_insert (key_table, (char *) "ldflda", GINT_TO_POINTER (TRUE));
2160         g_hash_table_insert (key_table, (char *) "ldftn", GINT_TO_POINTER (TRUE));
2161         g_hash_table_insert (key_table, (char *) "ldind.i", GINT_TO_POINTER (TRUE));
2162         g_hash_table_insert (key_table, (char *) "ldind.i1", GINT_TO_POINTER (TRUE));
2163         g_hash_table_insert (key_table, (char *) "ldind.i2", GINT_TO_POINTER (TRUE));
2164         g_hash_table_insert (key_table, (char *) "ldind.i4", GINT_TO_POINTER (TRUE));
2165         g_hash_table_insert (key_table, (char *) "ldind.i8", GINT_TO_POINTER (TRUE));
2166         g_hash_table_insert (key_table, (char *) "ldind.r4", GINT_TO_POINTER (TRUE));
2167         g_hash_table_insert (key_table, (char *) "ldind.r8", GINT_TO_POINTER (TRUE));
2168         g_hash_table_insert (key_table, (char *) "ldind.ref", GINT_TO_POINTER (TRUE));
2169         g_hash_table_insert (key_table, (char *) "ldind.u1", GINT_TO_POINTER (TRUE));
2170         g_hash_table_insert (key_table, (char *) "ldind.u2", GINT_TO_POINTER (TRUE));
2171         g_hash_table_insert (key_table, (char *) "ldind.u4", GINT_TO_POINTER (TRUE));
2172         g_hash_table_insert (key_table, (char *) "ldind.u8", GINT_TO_POINTER (TRUE));
2173         g_hash_table_insert (key_table, (char *) "ldlen", GINT_TO_POINTER (TRUE));
2174         g_hash_table_insert (key_table, (char *) "ldloc", GINT_TO_POINTER (TRUE));
2175         g_hash_table_insert (key_table, (char *) "ldloc.0", GINT_TO_POINTER (TRUE));
2176         g_hash_table_insert (key_table, (char *) "ldloc.1", GINT_TO_POINTER (TRUE));
2177         g_hash_table_insert (key_table, (char *) "ldloc.2", GINT_TO_POINTER (TRUE));
2178         g_hash_table_insert (key_table, (char *) "ldloc.3", GINT_TO_POINTER (TRUE));
2179         g_hash_table_insert (key_table, (char *) "ldloc.s", GINT_TO_POINTER (TRUE));
2180         g_hash_table_insert (key_table, (char *) "ldloca", GINT_TO_POINTER (TRUE));
2181         g_hash_table_insert (key_table, (char *) "ldloca.s", GINT_TO_POINTER (TRUE));
2182         g_hash_table_insert (key_table, (char *) "ldnull", GINT_TO_POINTER (TRUE));
2183         g_hash_table_insert (key_table, (char *) "ldobj", GINT_TO_POINTER (TRUE));
2184         g_hash_table_insert (key_table, (char *) "ldsfld", GINT_TO_POINTER (TRUE));
2185         g_hash_table_insert (key_table, (char *) "ldsflda", GINT_TO_POINTER (TRUE));
2186         g_hash_table_insert (key_table, (char *) "ldstr", GINT_TO_POINTER (TRUE));
2187         g_hash_table_insert (key_table, (char *) "ldtoken", GINT_TO_POINTER (TRUE));
2188         g_hash_table_insert (key_table, (char *) "ldvirtftn", GINT_TO_POINTER (TRUE));
2189         g_hash_table_insert (key_table, (char *) "leave", GINT_TO_POINTER (TRUE));
2190         g_hash_table_insert (key_table, (char *) "leave.s", GINT_TO_POINTER (TRUE));
2191         g_hash_table_insert (key_table, (char *) "linkcheck", GINT_TO_POINTER (TRUE));
2192         g_hash_table_insert (key_table, (char *) "literal", GINT_TO_POINTER (TRUE));
2193         g_hash_table_insert (key_table, (char *) "localloc", GINT_TO_POINTER (TRUE));
2194         g_hash_table_insert (key_table, (char *) "lpstr", GINT_TO_POINTER (TRUE));
2195         g_hash_table_insert (key_table, (char *) "lpstruct", GINT_TO_POINTER (TRUE));
2196         g_hash_table_insert (key_table, (char *) "lptstr", GINT_TO_POINTER (TRUE));
2197         g_hash_table_insert (key_table, (char *) "lpvoid", GINT_TO_POINTER (TRUE));
2198         g_hash_table_insert (key_table, (char *) "lpwstr", GINT_TO_POINTER (TRUE));
2199         g_hash_table_insert (key_table, (char *) "managed", GINT_TO_POINTER (TRUE));
2200         g_hash_table_insert (key_table, (char *) "marshal", GINT_TO_POINTER (TRUE));
2201         g_hash_table_insert (key_table, (char *) "method", GINT_TO_POINTER (TRUE));
2202         g_hash_table_insert (key_table, (char *) "mkrefany", GINT_TO_POINTER (TRUE));
2203         g_hash_table_insert (key_table, (char *) "modopt", GINT_TO_POINTER (TRUE));
2204         g_hash_table_insert (key_table, (char *) "modreq", GINT_TO_POINTER (TRUE));
2205         g_hash_table_insert (key_table, (char *) "mul", GINT_TO_POINTER (TRUE));
2206         g_hash_table_insert (key_table, (char *) "mul.ovf", GINT_TO_POINTER (TRUE));
2207         g_hash_table_insert (key_table, (char *) "mul.ovf.un", GINT_TO_POINTER (TRUE));
2208         g_hash_table_insert (key_table, (char *) "native", GINT_TO_POINTER (TRUE));
2209         g_hash_table_insert (key_table, (char *) "neg", GINT_TO_POINTER (TRUE));
2210         g_hash_table_insert (key_table, (char *) "nested", GINT_TO_POINTER (TRUE));
2211         g_hash_table_insert (key_table, (char *) "newarr", GINT_TO_POINTER (TRUE));
2212         g_hash_table_insert (key_table, (char *) "newobj", GINT_TO_POINTER (TRUE));
2213         g_hash_table_insert (key_table, (char *) "newslot", GINT_TO_POINTER (TRUE));
2214         g_hash_table_insert (key_table, (char *) "noappdomain", GINT_TO_POINTER (TRUE));
2215         g_hash_table_insert (key_table, (char *) "noinlining", GINT_TO_POINTER (TRUE));
2216         g_hash_table_insert (key_table, (char *) "nomachine", GINT_TO_POINTER (TRUE));
2217         g_hash_table_insert (key_table, (char *) "nomangle", GINT_TO_POINTER (TRUE));
2218         g_hash_table_insert (key_table, (char *) "nometadata", GINT_TO_POINTER (TRUE));
2219         g_hash_table_insert (key_table, (char *) "noncasdemand", GINT_TO_POINTER (TRUE));
2220         g_hash_table_insert (key_table, (char *) "noncasinheritance", GINT_TO_POINTER (TRUE));
2221         g_hash_table_insert (key_table, (char *) "noncaslinkdemand", GINT_TO_POINTER (TRUE));
2222         g_hash_table_insert (key_table, (char *) "nop", GINT_TO_POINTER (TRUE));
2223         g_hash_table_insert (key_table, (char *) "noprocess", GINT_TO_POINTER (TRUE));
2224         g_hash_table_insert (key_table, (char *) "not", GINT_TO_POINTER (TRUE));
2225         g_hash_table_insert (key_table, (char *) "not_in_gc_heap", GINT_TO_POINTER (TRUE));
2226         g_hash_table_insert (key_table, (char *) "notremotable", GINT_TO_POINTER (TRUE));
2227         g_hash_table_insert (key_table, (char *) "notserialized", GINT_TO_POINTER (TRUE));
2228         g_hash_table_insert (key_table, (char *) "null", GINT_TO_POINTER (TRUE));
2229         g_hash_table_insert (key_table, (char *) "nullref", GINT_TO_POINTER (TRUE));
2230         g_hash_table_insert (key_table, (char *) "object", GINT_TO_POINTER (TRUE));
2231         g_hash_table_insert (key_table, (char *) "objectref", GINT_TO_POINTER (TRUE));
2232         g_hash_table_insert (key_table, (char *) "opt", GINT_TO_POINTER (TRUE));
2233         g_hash_table_insert (key_table, (char *) "optil", GINT_TO_POINTER (TRUE));
2234         g_hash_table_insert (key_table, (char *) "or", GINT_TO_POINTER (TRUE));
2235         g_hash_table_insert (key_table, (char *) "out", GINT_TO_POINTER (TRUE));
2236         g_hash_table_insert (key_table, (char *) "permitonly", GINT_TO_POINTER (TRUE));
2237         g_hash_table_insert (key_table, (char *) "pinned", GINT_TO_POINTER (TRUE));
2238         g_hash_table_insert (key_table, (char *) "pinvokeimpl", GINT_TO_POINTER (TRUE));
2239         g_hash_table_insert (key_table, (char *) "pop", GINT_TO_POINTER (TRUE));
2240         g_hash_table_insert (key_table, (char *) "prefix1", GINT_TO_POINTER (TRUE));
2241         g_hash_table_insert (key_table, (char *) "prefix2", GINT_TO_POINTER (TRUE));
2242         g_hash_table_insert (key_table, (char *) "prefix3", GINT_TO_POINTER (TRUE));
2243         g_hash_table_insert (key_table, (char *) "prefix4", GINT_TO_POINTER (TRUE));
2244         g_hash_table_insert (key_table, (char *) "prefix5", GINT_TO_POINTER (TRUE));
2245         g_hash_table_insert (key_table, (char *) "prefix6", GINT_TO_POINTER (TRUE));
2246         g_hash_table_insert (key_table, (char *) "prefix7", GINT_TO_POINTER (TRUE));
2247         g_hash_table_insert (key_table, (char *) "prefixref", GINT_TO_POINTER (TRUE));
2248         g_hash_table_insert (key_table, (char *) "prejitdeny", GINT_TO_POINTER (TRUE));
2249         g_hash_table_insert (key_table, (char *) "prejitgrant", GINT_TO_POINTER (TRUE));
2250         g_hash_table_insert (key_table, (char *) "preservesig", GINT_TO_POINTER (TRUE));
2251         g_hash_table_insert (key_table, (char *) "private", GINT_TO_POINTER (TRUE));
2252         g_hash_table_insert (key_table, (char *) "Compilercontrolled", GINT_TO_POINTER (TRUE));
2253         g_hash_table_insert (key_table, (char *) "protected", GINT_TO_POINTER (TRUE));
2254         g_hash_table_insert (key_table, (char *) "public", GINT_TO_POINTER (TRUE));
2255         g_hash_table_insert (key_table, (char *) "readonly", GINT_TO_POINTER (TRUE));
2256         g_hash_table_insert (key_table, (char *) "record", GINT_TO_POINTER (TRUE));
2257         g_hash_table_insert (key_table, (char *) "refany", GINT_TO_POINTER (TRUE));
2258         g_hash_table_insert (key_table, (char *) "refanytype", GINT_TO_POINTER (TRUE));
2259         g_hash_table_insert (key_table, (char *) "refanyval", GINT_TO_POINTER (TRUE));
2260         g_hash_table_insert (key_table, (char *) "rem", GINT_TO_POINTER (TRUE));
2261         g_hash_table_insert (key_table, (char *) "rem.un", GINT_TO_POINTER (TRUE));
2262         g_hash_table_insert (key_table, (char *) "reqmin", GINT_TO_POINTER (TRUE));
2263         g_hash_table_insert (key_table, (char *) "reqopt", GINT_TO_POINTER (TRUE));
2264         g_hash_table_insert (key_table, (char *) "reqrefuse", GINT_TO_POINTER (TRUE));
2265         g_hash_table_insert (key_table, (char *) "reqsecobj", GINT_TO_POINTER (TRUE));
2266         g_hash_table_insert (key_table, (char *) "request", GINT_TO_POINTER (TRUE));
2267         g_hash_table_insert (key_table, (char *) "ret", GINT_TO_POINTER (TRUE));
2268         g_hash_table_insert (key_table, (char *) "rethrow", GINT_TO_POINTER (TRUE));
2269         g_hash_table_insert (key_table, (char *) "retval", GINT_TO_POINTER (TRUE));
2270         g_hash_table_insert (key_table, (char *) "rtspecialname", GINT_TO_POINTER (TRUE));
2271         g_hash_table_insert (key_table, (char *) "runtime", GINT_TO_POINTER (TRUE));
2272         g_hash_table_insert (key_table, (char *) "safearray", GINT_TO_POINTER (TRUE));
2273         g_hash_table_insert (key_table, (char *) "sealed", GINT_TO_POINTER (TRUE));
2274         g_hash_table_insert (key_table, (char *) "sequential", GINT_TO_POINTER (TRUE));
2275         g_hash_table_insert (key_table, (char *) "serializable", GINT_TO_POINTER (TRUE));
2276         g_hash_table_insert (key_table, (char *) "shl", GINT_TO_POINTER (TRUE));
2277         g_hash_table_insert (key_table, (char *) "shr", GINT_TO_POINTER (TRUE));
2278         g_hash_table_insert (key_table, (char *) "shr.un", GINT_TO_POINTER (TRUE));
2279         g_hash_table_insert (key_table, (char *) "sizeof", GINT_TO_POINTER (TRUE));
2280         g_hash_table_insert (key_table, (char *) "special", GINT_TO_POINTER (TRUE));
2281         g_hash_table_insert (key_table, (char *) "specialname", GINT_TO_POINTER (TRUE));
2282         g_hash_table_insert (key_table, (char *) "starg", GINT_TO_POINTER (TRUE));
2283         g_hash_table_insert (key_table, (char *) "starg.s", GINT_TO_POINTER (TRUE));
2284         g_hash_table_insert (key_table, (char *) "static", GINT_TO_POINTER (TRUE));
2285         g_hash_table_insert (key_table, (char *) "stdcall", GINT_TO_POINTER (TRUE));
2286         g_hash_table_insert (key_table, (char *) "stdcall", GINT_TO_POINTER (TRUE));
2287         g_hash_table_insert (key_table, (char *) "stelem.i", GINT_TO_POINTER (TRUE));
2288         g_hash_table_insert (key_table, (char *) "stelem.i1", GINT_TO_POINTER (TRUE));
2289         g_hash_table_insert (key_table, (char *) "stelem.i2", GINT_TO_POINTER (TRUE));
2290         g_hash_table_insert (key_table, (char *) "stelem.i4", GINT_TO_POINTER (TRUE));
2291         g_hash_table_insert (key_table, (char *) "stelem.i8", GINT_TO_POINTER (TRUE));
2292         g_hash_table_insert (key_table, (char *) "stelem.r4", GINT_TO_POINTER (TRUE));
2293         g_hash_table_insert (key_table, (char *) "stelem.r8", GINT_TO_POINTER (TRUE));
2294         g_hash_table_insert (key_table, (char *) "stelem.ref", GINT_TO_POINTER (TRUE));
2295         g_hash_table_insert (key_table, (char *) "stfld", GINT_TO_POINTER (TRUE));
2296         g_hash_table_insert (key_table, (char *) "stind.i", GINT_TO_POINTER (TRUE));
2297         g_hash_table_insert (key_table, (char *) "stind.i1", GINT_TO_POINTER (TRUE));
2298         g_hash_table_insert (key_table, (char *) "stind.i2", GINT_TO_POINTER (TRUE));
2299         g_hash_table_insert (key_table, (char *) "stind.i4", GINT_TO_POINTER (TRUE));
2300         g_hash_table_insert (key_table, (char *) "stind.i8", GINT_TO_POINTER (TRUE));
2301         g_hash_table_insert (key_table, (char *) "stind.r4", GINT_TO_POINTER (TRUE));
2302         g_hash_table_insert (key_table, (char *) "stind.r8", GINT_TO_POINTER (TRUE));
2303         g_hash_table_insert (key_table, (char *) "to", GINT_TO_POINTER (TRUE));
2304         g_hash_table_insert (key_table, (char *) "value", GINT_TO_POINTER (TRUE));
2305 }