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