2 * get.c: Functions to get stringified values from the metadata tables.
5 * Miguel de Icaza (miguel@ximian.com)
7 * (C) 2001 Ximian, Inc.
18 #include <mono/metadata/class.h>
21 get_typedef (MonoMetadata *m, int idx)
23 guint32 cols [MONO_TYPEDEF_SIZE];
25 mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPEDEF], idx - 1, cols, MONO_TYPEDEF_SIZE);
27 return g_strdup_printf (
29 mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAMESPACE]),
30 mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAME]));
34 get_module (MonoMetadata *m, int idx)
36 guint32 cols [MONO_MODULE_SIZE];
39 * There MUST BE only one module in the Module table
43 mono_metadata_decode_row (&m->tables [MONO_TABLE_MODULEREF], idx - 1, cols, MONO_MODULE_SIZE);
45 return g_strdup (mono_metadata_string_heap (m, cols [MONO_MODULE_NAME]));
49 get_assemblyref (MonoMetadata *m, int idx)
51 guint32 cols [MONO_ASSEMBLYREF_SIZE];
53 mono_metadata_decode_row (&m->tables [MONO_TABLE_ASSEMBLYREF], idx - 1, cols, MONO_ASSEMBLYREF_SIZE);
55 return g_strdup (mono_metadata_string_heap (m, cols [MONO_ASSEMBLYREF_NAME]));
60 * Returns a string representing the ArrayShape (22.2.16).
63 get_array_shape (MonoMetadata *m, const char *ptr, char **result)
65 GString *res = g_string_new ("[");
66 guint32 rank, num_sizes, num_lo_bounds;
67 guint32 *sizes = NULL, *lo_bounds = NULL;
71 rank = mono_metadata_decode_value (ptr, &ptr);
72 num_sizes = mono_metadata_decode_value (ptr, &ptr);
75 sizes = g_new (guint32, num_sizes);
77 for (i = 0; i < num_sizes; i++)
78 sizes [i] = mono_metadata_decode_value (ptr, &ptr);
80 num_lo_bounds = mono_metadata_decode_value (ptr, &ptr);
81 if (num_lo_bounds > 0)
82 lo_bounds = g_new (guint32, num_lo_bounds);
84 for (i = 0; i < num_lo_bounds; i++)
85 lo_bounds [i] = mono_metadata_decode_value (ptr, &ptr);
87 for (r = 0; r < rank; r++){
89 if (r < num_lo_bounds){
90 sprintf (buffer, "%d..%d", lo_bounds [r], lo_bounds [r] + sizes [r] - 1);
92 sprintf (buffer, "0..%d", sizes [r] - 1);
97 g_string_append (res, buffer);
99 g_string_append (res, ", ");
101 g_string_append (res, "]");
110 g_string_free (res, FALSE);
117 * @m: metadata context
118 * @blob_idx: index into the blob heap
120 * Returns the stringified representation of a TypeSpec signature (22.2.17)
123 get_typespec (MonoMetadata *m, guint32 idx)
125 guint32 cols [MONO_TYPESPEC_SIZE];
128 GString *res = g_string_new ("");
131 mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPESPEC], idx-1, cols, MONO_TYPESPEC_SIZE);
132 ptr = mono_metadata_blob_heap (m, cols [MONO_TYPESPEC_SIGNATURE]);
133 len = mono_metadata_decode_value (ptr, &ptr);
137 ptr = get_custom_mod (m, ptr, &s);
139 g_string_append (res, s);
140 g_string_append_c (res, ' ');
144 if (*ptr == MONO_TYPE_VOID)
145 g_string_append (res, "void");
147 ptr = get_type (m, ptr, &s);
149 g_string_append (res, s);
153 case MONO_TYPE_FNPTR:
154 g_string_append (res, "FNPTR ");
156 * we assume MethodRefSig, as we do not know
157 * whether it is a MethodDefSig or a MethodRefSig.
159 printf ("\n FNPTR:\n");
161 hex_dump (ptr, 0, 40);
164 case MONO_TYPE_ARRAY:
165 ptr = get_type (m, ptr, &s);
166 g_string_append (res, s);
168 g_string_append_c (res, ' ');
169 ptr = get_array_shape (m, ptr, &s);
170 g_string_append (res, s);
174 case MONO_TYPE_SZARRAY:
175 ptr = get_custom_mod (m, ptr, &s);
177 g_string_append (res, s);
178 g_string_append_c (res, ' ');
181 ptr = get_type (m, ptr, &s);
182 g_string_append (res, s);
183 g_string_append (res, "[]");
188 g_string_free (res, FALSE);
194 get_typeref (MonoMetadata *m, int idx)
196 guint32 cols [MONO_TYPEREF_SIZE];
199 guint32 rs_idx, table;
201 mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPEREF], idx - 1, cols, MONO_TYPEREF_SIZE);
203 t = mono_metadata_string_heap (m, cols [MONO_TYPEREF_NAME]);
204 s = mono_metadata_string_heap (m, cols [MONO_TYPEREF_NAMESPACE]);
206 rs_idx = cols [MONO_TYPEREF_SCOPE] >> 2;
209 * ECMA spec claims 3 bits
211 table = cols [MONO_TYPEREF_SCOPE] & 3;
215 x = get_module (m, rs_idx);
216 ret = g_strdup_printf ("TODO:TypeRef-Module [%s] %s.%s", x, s, t);
220 case 1: /* ModuleRef */
221 ret = g_strdup_printf ("TODO:TypeRef-ModuleRef (%s.%s)", s, t);
225 * AssemblyRef (ECMA docs claim it is 3, but it looks to
226 * me like it is 2 (tokens are prefixed with 0x23)
228 x = get_assemblyref (m, rs_idx);
229 ret = g_strdup_printf ("[%s] %s.%s", x, s, t);
233 case 4: /* TypeRef */
234 ret = g_strdup_printf ("TODO:TypeRef-TypeRef: TYPEREF! (%s.%s)", s, t);
238 ret = g_strdup_printf ("Unknown table in TypeRef %d", table);
245 * get_typedef_or_ref:
246 * @m: metadata context
247 * @dor_token: def or ref encoded index
249 * Low two bits contain table to lookup from
250 * high bits contain the index into the def or ref table
252 * Returns: a stringified version of the MethodDef or MethodRef
253 * at (dor_token >> 2)
256 get_typedef_or_ref (MonoMetadata *m, guint32 dor_token)
258 char *temp = NULL, *s;
262 * low 2 bits contain encoding
264 table = dor_token & 0x03;
265 idx = dor_token >> 2;
268 case 0: /* TypeDef */
269 temp = get_typedef (m, idx);
270 s = g_strdup_printf ("%s", temp);
273 case 1: /* TypeRef */
274 temp = get_typeref (m, idx);
275 s = g_strdup_printf ("%s", temp);
278 case 2: /* TypeSpec */
279 s = get_typespec (m, idx);
283 g_error ("Unhandled encoding for typedef-or-ref coded index");
294 * get_encoded_typedef_or_ref:
295 * @m: metadata context
296 * @ptr: location to decode from.
297 * @result: pointer to string where resulting decoded string is stored
299 * result will point to a g_malloc()ed string.
301 * Returns: the new ptr to continue decoding
304 get_encoded_typedef_or_ref (MonoMetadata *m, const char *ptr, char **result)
308 token = mono_metadata_decode_value (ptr, &ptr);
310 *result = get_typedef_or_ref (m, token);
318 * Decodes a CustomMod (22.2.7)
320 * Returns: updated pointer location
323 get_custom_mod (MonoMetadata *m, const char *ptr, char **return_value)
327 if ((*ptr == MONO_TYPE_CMOD_OPT) ||
328 (*ptr == MONO_TYPE_CMOD_REQD)){
330 ptr = get_encoded_typedef_or_ref (m, ptr, &s);
332 *return_value = g_strconcat ("CMOD ", s, NULL);
335 *return_value = NULL;
340 static map_t element_type_map [] = {
341 { MONO_TYPE_END , "end" },
342 { MONO_TYPE_VOID , "void" },
343 { MONO_TYPE_BOOLEAN , "bool" },
344 { MONO_TYPE_CHAR , "char" },
345 { MONO_TYPE_I1 , "sbyte" },
346 { MONO_TYPE_U1 , "byte" },
347 { MONO_TYPE_I2 , "int16" },
348 { MONO_TYPE_U2 , "uint16" },
349 { MONO_TYPE_I4 , "int32" },
350 { MONO_TYPE_U4 , "uint32" },
351 { MONO_TYPE_I8 , "int64" },
352 { MONO_TYPE_U8 , "uint64" },
353 { MONO_TYPE_R4 , "float32" },
354 { MONO_TYPE_R8 , "float64" },
355 { MONO_TYPE_STRING , "string" },
356 { MONO_TYPE_TYPEDBYREF , "TypedByRef" },
357 { MONO_TYPE_I , "native int" },
358 { MONO_TYPE_U , "native unsigned int" },
359 { MONO_TYPE_OBJECT , "object" },
363 static map_t call_conv_type_map [] = {
364 { MONO_CALL_DEFAULT , "default" },
365 { MONO_CALL_C , "c" },
366 { MONO_CALL_STDCALL , "stdcall" },
367 { MONO_CALL_THISCALL , "thiscall" },
368 { MONO_CALL_FASTCALL , "fastcall" },
369 { MONO_CALL_VARARG , "vararg" },
374 dis_stringify_token (MonoMetadata *m, guint32 token)
376 guint idx = token & 0xffffff;
377 switch (token >> 24) {
378 case MONO_TABLE_TYPEDEF: return get_typedef (m, idx);
379 case MONO_TABLE_TYPEREF: return get_typeref (m, idx);
380 case MONO_TABLE_TYPESPEC: return get_typespec (m, idx);
384 return g_strdup_printf("0x%08x", token);
388 dis_stringify_array (MonoMetadata *m, MonoArray *array)
391 GString *s = g_string_new("");
394 type = dis_stringify_type (m, array->type);
395 g_string_append (s, type);
397 g_string_append_c (s, '[');
398 for (i = 0; i < array->rank; ++i) {
400 g_string_append_c (s, ',');
401 if (i < array->numsizes) {
402 if (i < array->numlobounds && array->lobounds[i] != 0)
403 g_string_sprintfa (s, "%d..%d", array->lobounds[i], array->sizes[i]);
405 g_string_sprintfa (s, "%d", array->sizes[i]);
408 g_string_append_c (s, ']');
410 g_string_free (s, FALSE);
415 dis_stringify_modifiers (MonoMetadata *m, int n, MonoCustomMod *mod)
417 GString *s = g_string_new("");
420 for (i = 0; i < n; ++i) {
421 char *tok = dis_stringify_token (m, mod[i].token);
422 g_string_sprintfa (s, "%s %s", mod[i].required ? "opt": "reqd", tok);
425 g_string_append_c (s, ' ');
427 g_string_free (s, FALSE);
432 dis_stringify_param (MonoMetadata *m, MonoType *param)
436 char *out = param->attrs & 2 ? "[out] ": "";
437 t = dis_stringify_type (m, param);
438 result = g_strconcat (out, t, NULL);
444 dis_stringify_method_signature (MonoMetadata *m, MonoMethodSignature *method, int methoddef_row)
446 guint32 cols [MONO_METHOD_SIZE];
447 guint32 pcols [MONO_PARAM_SIZE];
448 guint32 param_index = 0;
449 const char *name = "";
452 GString *result = g_string_new ("");
455 g_assert (method || methoddef_row);
458 mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD], methoddef_row -1, cols, MONO_METHOD_SIZE);
459 name = mono_metadata_string_heap (m, cols [MONO_METHOD_NAME]);
460 param_index = cols [MONO_METHOD_PARAMLIST];
462 const char *sig = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]);
463 mono_metadata_decode_blob_size (sig, &sig);
464 method = mono_metadata_parse_method_signature (m, 1, sig, &sig);
469 retval = dis_stringify_param (m, method->ret);
471 g_string_append (result, "instance ");
472 g_string_append (result, map (method->call_convention, call_conv_type_map));
473 g_string_sprintfa (result, " %s %s (", retval, name);
475 for (i = 0; i < method->param_count; ++i) {
477 mono_metadata_decode_row (&m->tables [MONO_TABLE_PARAM], param_index - 1, pcols, MONO_PARAM_SIZE);
478 name = mono_metadata_string_heap (m, pcols [MONO_PARAM_NAME]);
479 method->params [i]->attrs = pcols [MONO_PARAM_FLAGS];
485 g_string_append (result, ", ");
486 retval = dis_stringify_param (m, method->params [i]);
487 g_string_sprintfa (result, "%s %s", retval, name);
490 g_string_append (result, ") ");
493 mono_metadata_free_method_signature (method);
494 retval = result->str;
495 g_string_free (result, FALSE);
501 dis_stringify_type (MonoMetadata *m, MonoType *type)
503 char *bare = NULL, *pinned = "", *byref = "";
508 mods = dis_stringify_modifiers (m, type->num_mods, type->modifiers);
511 case MONO_TYPE_BOOLEAN:
525 case MONO_TYPE_STRING:
526 case MONO_TYPE_OBJECT:
527 case MONO_TYPE_TYPEDBYREF:
528 bare = g_strdup (map (type->type, element_type_map));
531 case MONO_TYPE_VALUETYPE:
532 case MONO_TYPE_CLASS:
533 bare = dis_stringify_token (type->data.klass->image, type->data.klass->type_token);
536 case MONO_TYPE_FNPTR:
537 bare = dis_stringify_method_signature (m, type->data.method, 0);
540 case MONO_TYPE_SZARRAY: {
542 child_type = dis_stringify_type (m, type->data.type);
544 bare = g_strdup_printf (type->type == MONO_TYPE_PTR ? "%s*" : "%s[]", child_type);
548 case MONO_TYPE_ARRAY:
549 bare = dis_stringify_array (m, type->data.array);
552 bare = g_strdup ("void");
555 g_error ("Do not know how to stringify type 0x%x", type->type);
564 result = g_strconcat (mods ? mods : "", bare, byref, pinned, NULL);
573 * @m: metadata context
574 * @ptr: location to decode from.
575 * @result: pointer to string where resulting decoded string is stored
577 * This routine returs in @result the stringified type pointed by @ptr.
580 * Returns: the new ptr to continue decoding
583 get_type (MonoMetadata *m, const char *ptr, char **result)
585 MonoType *type = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
586 *result = dis_stringify_type (m, type);
587 mono_metadata_free_type (type);
593 * Returns a stringified representation of a FieldSig (22.2.4)
596 get_field_signature (MonoMetadata *m, guint32 blob_signature)
598 char *allocated_modifier_string, *allocated_type_string;
599 const char *ptr = mono_metadata_blob_heap (m, blob_signature);
604 len = mono_metadata_decode_value (ptr, &ptr);
607 g_assert (*ptr == 0x06);
608 /* hex_dump (ptr, 0, len); */
611 ptr = get_custom_mod (m, ptr, &allocated_modifier_string);
612 ptr = get_type (m, ptr, &allocated_type_string);
614 res = g_strdup_printf (
616 allocated_modifier_string ? allocated_modifier_string : "",
617 allocated_type_string);
619 if (allocated_modifier_string)
620 g_free (allocated_modifier_string);
621 if (allocated_type_string)
622 g_free (allocated_modifier_string);
628 get_field_literal_type (MonoMetadata *m, guint32 blob_signature)
630 const char *ptr = mono_metadata_blob_heap (m, blob_signature);
632 char *allocated_modifier_string;
634 len = mono_metadata_decode_value (ptr, &ptr);
637 g_assert (*ptr == 0x06);
640 ptr = get_custom_mod (m, ptr, &allocated_modifier_string);
641 if (allocated_modifier_string)
642 g_free (allocated_modifier_string);
644 return (MonoTypeEnum) *ptr;
650 * @m: metadata context
651 * @token: token to decode
653 * decodes the literal indexed by @token.
656 decode_literal (MonoMetadata *m, guint32 token)
658 return g_strdup ("LITERAL_VALUE");
663 * @m: metadata context
664 * @ptr: location to decode from.
665 * @result: pointer to string where resulting decoded string is stored
667 * This routine returns in @result the stringified RetType (22.2.11)
669 * Returns: the new ptr to continue decoding.
672 get_ret_type (MonoMetadata *m, const char *ptr, char **ret_type)
674 GString *str = g_string_new ("");
676 char *allocated_type_string;
678 ptr = get_custom_mod (m, ptr, &mod);
680 g_string_append (str, mod);
681 g_string_append_c (str, ' ');
685 if (*ptr == MONO_TYPE_TYPEDBYREF){
686 /* TODO: what does `typedbyref' mean? */
687 g_string_append (str, "/* FIXME: What does this mean? */ typedbyref ");
689 } else if (*ptr == MONO_TYPE_VOID){
690 g_string_append (str, "void");
693 if (*ptr == MONO_TYPE_BYREF){
694 g_string_append (str, "[out] ");
698 ptr = get_type (m, ptr, &allocated_type_string);
699 g_string_append (str, allocated_type_string);
700 g_free (allocated_type_string);
703 *ret_type = str->str;
704 g_string_free (str, FALSE);
711 * @m: metadata context
712 * @ptr: location to decode from.
713 * @result: pointer to string where resulting decoded string is stored
715 * This routine returns in @result the stringified Param (22.2.10)
717 * Returns: the new ptr to continue decoding.
720 get_param (MonoMetadata *m, const char *ptr, char **retval)
722 GString *str = g_string_new ("");
723 char *allocated_mod_string, *allocated_type_string;
725 ptr = get_custom_mod (m, ptr, &allocated_mod_string);
726 if (allocated_mod_string){
727 g_string_append (str, allocated_mod_string);
728 g_string_append_c (str, ' ');
729 g_free (allocated_mod_string);
732 if (*ptr == MONO_TYPE_TYPEDBYREF){
733 g_string_append (str, "/*FIXME: what does typedbyref mean? */ typedbyref ");
736 if (*ptr == MONO_TYPE_BYREF){
737 g_string_append (str, "[out] ");
740 ptr = get_type (m, ptr, &allocated_type_string);
741 g_string_append (str, allocated_type_string);
742 g_free (allocated_type_string);
746 g_string_free (str, FALSE);
750 static map_t param_map [] = {
751 { PARAM_ATTRIBUTE_IN, "[in] " },
752 { PARAM_ATTRIBUTE_OUT, "[out] " },
753 { PARAM_ATTRIBUTE_OPTIONAL, "optional " },
754 { PARAM_ATTRIBUTE_HAS_DEFAULT, "hasdefault " },
755 { PARAM_ATTRIBUTE_HAS_FIELD_MARSHAL, "fieldmarshal " },
760 param_flags (guint32 f)
762 return g_strdup (flags (f, param_map));
765 static map_t field_access_map [] = {
766 { FIELD_ATTRIBUTE_COMPILER_CONTROLLED, "compilercontrolled " },
767 { FIELD_ATTRIBUTE_PRIVATE, "private " },
768 { FIELD_ATTRIBUTE_FAM_AND_ASSEM, "famandassem " },
769 { FIELD_ATTRIBUTE_ASSEMBLY, "assembly " },
770 { FIELD_ATTRIBUTE_FAMILY, "family " },
771 { FIELD_ATTRIBUTE_FAM_OR_ASSEM, "famorassem " },
772 { FIELD_ATTRIBUTE_PUBLIC, "public " },
776 static map_t field_flags_map [] = {
777 { FIELD_ATTRIBUTE_STATIC, "static " },
778 { FIELD_ATTRIBUTE_INIT_ONLY, "initonly " },
779 { FIELD_ATTRIBUTE_LITERAL, "literal " },
780 { FIELD_ATTRIBUTE_NOT_SERIALIZED, "notserialized " },
781 { FIELD_ATTRIBUTE_SPECIAL_NAME, "specialname " },
782 { FIELD_ATTRIBUTE_PINVOKE_IMPL, "FIXME:pinvokeimpl " },
789 * Returns a stringified version of a Field's flags
792 field_flags (guint32 f)
795 int access = f & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK;
799 strcat (buffer, map (access, field_access_map));
800 strcat (buffer, flags (f, field_flags_map));
801 return g_strdup (buffer);
805 * Returns a stringifed representation of a MethodRefSig (22.2.2)
808 get_methodref_signature (MonoMetadata *m, guint32 blob_signature, const char *fancy_name)
810 GString *res = g_string_new ("");
811 const char *ptr = mono_metadata_blob_heap (m, blob_signature);
812 char *allocated_ret_type, *s;
813 gboolean seen_vararg = 0;
814 int param_count, signature_len;
817 signature_len = mono_metadata_decode_value (ptr, &ptr);
821 g_string_append (res, "explicit-this ");
823 g_string_append (res, "instance "); /* has-this */
830 param_count = mono_metadata_decode_value (ptr, &ptr);
831 ptr = get_ret_type (m, ptr, &allocated_ret_type);
833 g_string_append (res, allocated_ret_type);
836 g_string_append_c (res, ' ');
837 g_string_append (res, fancy_name);
840 g_string_append (res, " (");
843 * param_count describes parameters *before* and *after*
844 * the vararg sentinel
846 for (i = 0; i < param_count; i++){
850 * If ptr is a SENTINEL
853 g_string_append (res, " varargs ");
857 ptr = get_param (m, ptr, ¶m);
858 g_string_append (res, param);
859 if (i+1 != param_count)
860 g_string_append (res, ", ");
863 g_string_append (res, ")");
868 g_free (allocated_ret_type);
870 g_string_free (res, FALSE);
876 * @m: metadata context
877 * @token: a FIELD_DEF token
879 * This routine has to locate the TypeDef that "owns" this Field.
880 * Since there is no backpointer in the Field table, we have to scan
881 * the TypeDef table and locate the actual "owner" of the field
884 get_field (MonoMetadata *m, guint32 token)
886 int idx = mono_metadata_token_index (token);
887 guint32 cols [MONO_FIELD_SIZE];
888 char *sig, *res, *type;
892 * We can get here also with a MenberRef token (for a field
893 * defined in another module/assembly, just like in get_method ()
895 if (mono_metadata_token_code (token) == MONO_TOKEN_MEMBER_REF) {
896 return g_strdup_printf ("fieldref-0x%08x", token);
898 g_assert (mono_metadata_token_code (token) == MONO_TOKEN_FIELD_DEF);
900 mono_metadata_decode_row (&m->tables [MONO_TABLE_FIELD], idx - 1, cols, MONO_FIELD_SIZE);
901 sig = get_field_signature (m, cols [MONO_FIELD_SIGNATURE]);
904 * To locate the actual "container" for this field, we have to scan
905 * the TypeDef table. LAME!
907 type_idx = mono_metadata_typedef_from_field (m, idx);
909 type = get_typedef (m, type_idx);
910 res = g_strdup_printf ("%s %s.%s",
912 mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]));
920 get_memberref_parent (MonoMetadata *m, guint32 mrp_token)
923 * mrp_index is a MemberRefParent coded index
925 guint32 table = mrp_token & 7;
926 guint32 idx = mrp_token >> 3;
929 case 0: /* TypeDef */
930 return get_typedef (m, idx);
932 case 1: /* TypeRef */
933 return get_typeref (m, idx);
935 case 2: /* ModuleRef */
936 return g_strdup_printf ("TODO:MemberRefParent-ModuleRef");
938 case 3: /* MethodDef */
939 return g_strdup ("TODO:MethodDef");
941 case 4: /* TypeSpec */
942 return get_typespec (m, idx);
944 g_assert_not_reached ();
950 * @m: metadata context
951 * @token: a METHOD_DEF or MEMBER_REF token
953 * This routine has to locate the TypeDef that "owns" this Field.
954 * Since there is no backpointer in the Field table, we have to scan
955 * the TypeDef table and locate the actual "owner" of the field
958 get_method (MonoMetadata *m, guint32 token)
960 int idx = mono_metadata_token_index (token);
961 guint32 member_cols [MONO_MEMBERREF_SIZE], method_cols [MONO_METHOD_SIZE];
962 char *res, *class, *fancy_name, *sig;
965 switch (mono_metadata_token_code (token)){
966 case MONO_TOKEN_METHOD_DEF:
967 mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD],
968 idx - 1, method_cols, MONO_METHOD_SIZE);
970 name = mono_metadata_string_heap (m, method_cols [MONO_METHOD_NAME]);
972 sig = get_methodref_signature (m, method_cols [MONO_METHOD_SIGNATURE], name);
975 case MONO_TOKEN_MEMBER_REF: {
977 mono_metadata_decode_row (&m->tables [MONO_TABLE_MEMBERREF],
978 idx - 1, member_cols, MONO_MEMBERREF_SIZE);
979 class = get_memberref_parent (m, member_cols [MONO_MEMBERREF_CLASS]);
980 fancy_name = g_strconcat (
982 mono_metadata_string_heap (m, member_cols [MONO_MEMBERREF_NAME]),
985 sig = get_methodref_signature (
986 m, member_cols [MONO_MEMBERREF_SIGNATURE], fancy_name);
989 res = g_strdup_printf ("%s", sig);
995 g_assert_not_reached ();
997 g_assert_not_reached ();
1003 * @m: metadata context
1004 * @blob_index: index into the blob where the constant is stored
1006 * Returns: An allocated value representing a stringified version of the
1010 get_constant (MonoMetadata *m, MonoTypeEnum t, guint32 blob_index)
1012 const char *ptr = mono_metadata_blob_heap (m, blob_index);
1015 len = mono_metadata_decode_value (ptr, &ptr);
1018 case MONO_TYPE_BOOLEAN:
1019 return g_strdup_printf ("%s", *ptr ? "true" : "false");
1021 case MONO_TYPE_CHAR:
1022 return g_strdup_printf ("%c", *ptr);
1025 return g_strdup_printf ("0x%02x", (int) (*ptr));
1029 return g_strdup_printf ("%d", (int) (*(gint16 *) ptr));
1032 return g_strdup_printf ("%d", *(gint32 *) ptr);
1036 * FIXME: This is not endian portable, does only
1037 * matter for debugging, but still.
1039 return g_strdup_printf ("0x%08x%08x", *(guint32 *) ptr, *(guint32 *) (ptr + 4));
1042 return g_strdup_printf ("0x%08x%08x", *(guint32 *) ptr, *(guint32 *) (ptr + 4));
1044 return g_strdup_printf ("%g", (double) (* (float *) ptr));
1047 return g_strdup_printf ("%g", * (double *) ptr);
1049 case MONO_TYPE_STRING: {
1053 for (i = 0; !ptr [i+1]; i += 2){
1058 case '\n': /* add more */
1062 res = g_malloc (len + e + 3);
1066 for (i = 0; i < len; i += 2){
1079 res[j++] = isprint (ptr [i]) ? ptr [i] : '.';
1088 case MONO_TYPE_CLASS:
1089 return g_strdup ("CLASS CONSTANT. MUST BE ZERO");
1092 * These are non CLS compliant:
1095 return g_strdup_printf ("%d", (int) *ptr);
1098 return g_strdup_printf ("0x%04x", (unsigned int) (*(guint16 *) ptr));
1101 return g_strdup_printf ("0x%04x", (unsigned int) (*(guint32 *) ptr));
1104 g_error ("Unknown MONO_TYPE (%d) on constant at Blob index (0x%08x)\n",
1105 (int) *ptr, blob_index);
1106 return g_strdup_printf ("Unknown");
1113 * @m: metadata context
1114 * @token: token that we want to decode.
1116 * Returns: An allocated value representing a stringified version of the
1120 get_token (MonoMetadata *m, guint32 token)
1122 guint32 idx = mono_metadata_token_index (token);
1124 switch (mono_metadata_token_code (token)){
1125 case MONO_TOKEN_FIELD_DEF:
1126 return (get_field (m, token));
1127 case MONO_TOKEN_TYPE_DEF:
1128 return get_typedef (m, idx);
1129 case MONO_TOKEN_TYPE_REF:
1130 return get_typeref (m, idx);
1131 case MONO_TOKEN_TYPE_SPEC:
1132 return get_typespec (m, idx);
1134 g_error ("Do not know how to decode tokens of type 0x%08x", token);
1137 g_assert_not_reached ();
1138 return g_strdup ("ERROR");
1143 * @m: metadata context
1144 * @token: the token can belong to any of the following tables:
1145 * MONO_TOKEN_TYPE_REF, MONO_TOKEN_TYPE_DEF, MONO_TOKEN_TYPE_SPEC
1147 * Returns: a stringified version of the MethodDef or MethodRef or TypeSpecn
1148 * at (token & 0xffffff)
1151 get_token_type (MonoMetadata *m, guint32 token)
1153 char *temp = NULL, *s;
1156 idx = mono_metadata_token_index (token);
1158 switch (mono_metadata_token_code (token)){
1159 case MONO_TOKEN_TYPE_DEF:
1160 temp = get_typedef (m, idx);
1161 s = g_strdup_printf ("%s", temp);
1164 case MONO_TOKEN_TYPE_REF:
1165 temp = get_typeref (m, idx);
1166 s = g_strdup_printf ("%s", temp);
1169 case MONO_TOKEN_TYPE_SPEC:
1170 s = get_typespec (m, idx);
1174 g_error ("Unhandled encoding for typedef-or-ref coded index");