#include <string.h>
#include <ctype.h>
#include <glib.h>
+#include <math.h>
#include "meta.h"
#include "util.h"
#include "get.h"
outer = get_typedef (m, mono_metadata_token_index (token));
result = g_strdup_printf (
- "%s%s%s/%s%s", ns, *ns?".":"", outer,
+ "%s/%s%s", outer,
mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAME]),
tstring ? tstring : "");
g_free (outer);
* Returns the stringified representation of a TypeSpec signature (22.2.17)
*/
char *
-get_typespec (MonoImage *m, guint32 idx, MonoGenericContext *context)
+get_typespec (MonoImage *m, guint32 idx, gboolean is_def, MonoGenericContext *context)
{
guint32 cols [MONO_TYPESPEC_SIZE];
const char *ptr;
g_free (s);
break;
- case MONO_TYPE_VAR:
- case MONO_TYPE_MVAR:
- ptr = get_type (m, ptr-1, &s, context);
- g_string_append (res, s);
- g_free (s);
- break;
-
default:
- s = dis_stringify_type (m, type);
+ s = dis_stringify_type (m, type, is_def);
g_string_append (res, s);
g_free (s);
break;
break;
case 2: /* TypeSpec */
- s = get_typespec (m, idx, context);
+ s = get_typespec (m, idx, FALSE, context);
break;
default:
{ MONO_TYPE_R4 , "float32" },
{ MONO_TYPE_R8 , "float64" },
{ MONO_TYPE_STRING , "string" },
- { MONO_TYPE_TYPEDBYREF , "TypedByRef" },
+ { MONO_TYPE_TYPEDBYREF , "typedref" },
{ MONO_TYPE_I , "native int" },
{ MONO_TYPE_U , "native unsigned int" },
{ MONO_TYPE_OBJECT , "object" },
switch (token >> 24) {
case MONO_TABLE_TYPEDEF: return get_typedef (m, idx);
case MONO_TABLE_TYPEREF: return get_typeref (m, idx);
- case MONO_TABLE_TYPESPEC: return get_typespec (m, idx, NULL);
+ case MONO_TABLE_TYPESPEC: return get_typespec (m, idx, FALSE, NULL);
default:
break;
}
}
char*
-dis_stringify_array (MonoImage *m, MonoArrayType *array)
+dis_stringify_array (MonoImage *m, MonoArrayType *array, gboolean is_def)
{
char *type;
GString *s = g_string_new("");
int i;
- type = dis_stringify_type (m, &array->eklass->byval_arg);
+ type = dis_stringify_type (m, &array->eklass->byval_arg, is_def);
g_string_append (s, type);
g_free (type);
g_string_append_c (s, '[');
char *t;
char *result;
char *attribs;
+ const char *in = param->attrs & PARAM_ATTRIBUTE_IN ? "[in]" : "";
const char *out = param->attrs & PARAM_ATTRIBUTE_OUT ? "[out]": "";
const char *opt = param->attrs & PARAM_ATTRIBUTE_OPTIONAL ? "[opt]": "";
- attribs = g_strconcat(out, opt, NULL);
- t = dis_stringify_type (m, param);
+ attribs = g_strconcat(in, out, opt, NULL);
+ t = dis_stringify_type (m, param, TRUE);
result = g_strjoin(attribs[0] ? " ":"", attribs, t, NULL);
g_free (t);
g_free (attribs);
return result;
}
+static char*
+dis_stringify_variant_type (MonoMarshalVariant variant)
+{
+ switch (variant) {
+ case MONO_VARIANT_EMPTY:
+ return g_strdup ("");
+ case MONO_VARIANT_NULL:
+ return g_strdup ("null");
+ case MONO_VARIANT_I2:
+ return g_strdup ("int16");
+ case MONO_VARIANT_I4:
+ return g_strdup ("int32");
+ case MONO_VARIANT_R4:
+ return g_strdup ("float32");
+ case MONO_VARIANT_R8:
+ return g_strdup ("float64");
+ case MONO_VARIANT_CY:
+ return g_strdup ("currency");
+ case MONO_VARIANT_DATE:
+ return g_strdup ("date");
+ case MONO_VARIANT_BSTR:
+ return g_strdup ("bstr");
+ case MONO_VARIANT_DISPATCH:
+ return g_strdup ("idispatch");
+ case MONO_VARIANT_ERROR:
+ return g_strdup ("error");
+ case MONO_VARIANT_BOOL:
+ return g_strdup ("bool");
+ case MONO_VARIANT_VARIANT:
+ return g_strdup ("variant");
+ case MONO_VARIANT_UNKNOWN:
+ return g_strdup ("iunknown");
+ case MONO_VARIANT_DECIMAL:
+ return g_strdup ("decimal");
+ case MONO_VARIANT_I1:
+ return g_strdup ("int8");
+ case MONO_VARIANT_UI1:
+ return g_strdup ("unsigned int8");
+ case MONO_VARIANT_UI2:
+ return g_strdup ("unsigned int16");
+ case MONO_VARIANT_UI4:
+ return g_strdup ("unsigned int32");
+ case MONO_VARIANT_I8:
+ return g_strdup ("int64");
+ case MONO_VARIANT_UI8:
+ return g_strdup ("unsigned int64");
+ case MONO_VARIANT_INT:
+ return g_strdup ("int");
+ case MONO_VARIANT_UINT:
+ return g_strdup ("unsigned int");
+ case MONO_VARIANT_VOID:
+ return g_strdup ("void");
+ case MONO_VARIANT_HRESULT:
+ return g_strdup ("hresult");
+ case MONO_VARIANT_PTR:
+ return g_strdup ("*");
+ case MONO_VARIANT_SAFEARRAY:
+ return g_strdup ("safearray");
+ case MONO_VARIANT_CARRAY:
+ return g_strdup ("carray");
+ case MONO_VARIANT_USERDEFINED:
+ return g_strdup ("userdefined");
+ case MONO_VARIANT_LPSTR:
+ return g_strdup ("lpstr");
+ case MONO_VARIANT_LPWSTR:
+ return g_strdup ("lpwstr");
+ case MONO_VARIANT_RECORD:
+ return g_strdup ("record");
+ case MONO_VARIANT_FILETIME:
+ return g_strdup ("filetime");
+ case MONO_VARIANT_BLOB:
+ return g_strdup ("blob");
+ case MONO_VARIANT_STREAM:
+ return g_strdup ("stream");
+ case MONO_VARIANT_STORAGE:
+ return g_strdup ("storage");
+ case MONO_VARIANT_STREAMED_OBJECT:
+ return g_strdup ("streamed_object");
+ case MONO_VARIANT_STORED_OBJECT:
+ return g_strdup ("stored_object");
+ case MONO_VARIANT_BLOB_OBJECT:
+ return g_strdup ("blob_object");
+ case MONO_VARIANT_CF:
+ return g_strdup ("cf");
+ case MONO_VARIANT_CLSID:
+ return g_strdup ("clsid");
+ case MONO_VARIANT_VECTOR:
+ /* FIXME: output: <v_type> vector */
+ return g_strdup ("vector");
+ case MONO_VARIANT_ARRAY:
+ /* FIXME: output: <v_type> [ ] */
+ return g_strdup ("[]");
+ case MONO_VARIANT_BYREF:
+ /* FIXME: output: <v_type> & */
+ return g_strdup ("&");
+ default:
+ return g_strdup ("unknown");
+ }
+}
+
+static char*
+dis_stringify_native_type (MonoMarshalNative native)
+{
+ switch (native) {
+ case MONO_NATIVE_BOOLEAN:
+ return g_strdup ("bool");
+ case MONO_NATIVE_I1:
+ return g_strdup ("int8");
+ case MONO_NATIVE_U1:
+ return g_strdup ("unsigned int8");
+ case MONO_NATIVE_I2:
+ return g_strdup ("int16");
+ case MONO_NATIVE_U2:
+ return g_strdup ("unsigned int16");
+ case MONO_NATIVE_I4:
+ return g_strdup ("int32");
+ case MONO_NATIVE_U4:
+ return g_strdup ("unsigned int32");
+ case MONO_NATIVE_I8:
+ return g_strdup ("int64");
+ case MONO_NATIVE_U8:
+ return g_strdup ("unsigned int64");
+ case MONO_NATIVE_R4:
+ return g_strdup ("float32");
+ case MONO_NATIVE_R8:
+ return g_strdup ("float64");
+ case MONO_NATIVE_CURRENCY:
+ return g_strdup ("currency");
+ case MONO_NATIVE_BSTR:
+ return g_strdup ("bstr");
+ case MONO_NATIVE_LPSTR:
+ return g_strdup ("lpstr");
+ case MONO_NATIVE_LPWSTR:
+ return g_strdup ("lpwstr");
+ case MONO_NATIVE_LPTSTR:
+ return g_strdup ("lptstr");
+ case MONO_NATIVE_IUNKNOWN:
+ return g_strdup ("iunknown");
+ case MONO_NATIVE_IDISPATCH:
+ return g_strdup ("idispatch");
+ case MONO_NATIVE_STRUCT:
+ return g_strdup ("struct");
+ case MONO_NATIVE_INTERFACE:
+ return g_strdup ("interface");
+ case MONO_NATIVE_SAFEARRAY:
+ return g_strdup ("safearray");
+ case MONO_NATIVE_INT:
+ return g_strdup ("int");
+ case MONO_NATIVE_UINT:
+ return g_strdup ("unsigned int");
+ case MONO_NATIVE_VBBYREFSTR:
+ return g_strdup ("vbbyrefstr");
+ case MONO_NATIVE_ANSIBSTR:
+ return g_strdup ("ansi bstr");
+ case MONO_NATIVE_TBSTR:
+ return g_strdup ("tbstr");
+ case MONO_NATIVE_VARIANTBOOL:
+ return g_strdup ("variant bool");
+ case MONO_NATIVE_FUNC:
+ return g_strdup ("method");
+ case MONO_NATIVE_ASANY:
+ return g_strdup ("as any");
+ case MONO_NATIVE_LPSTRUCT:
+ return g_strdup ("lpstruct");
+ case MONO_NATIVE_CUSTOM:
+ return g_strdup ("custom");
+ case MONO_NATIVE_ERROR:
+ return g_strdup ("error");
+ case MONO_NATIVE_MAX:
+ return g_strdup ("");
+ default:
+ return g_strdup ("unknown");
+ }
+}
+
+char*
+dis_stringify_marshal_spec (MonoMarshalSpec *spec)
+{
+ switch (spec->native) {
+ case MONO_NATIVE_BYVALTSTR:
+ return g_strdup_printf (" marshal (fixed sysstring [%d])", spec->data.array_data.num_elem);
+ case MONO_NATIVE_BYVALARRAY:
+ return g_strdup_printf (" marshal (fixed array [%d])", spec->data.array_data.num_elem);
+ case MONO_NATIVE_LPARRAY: {
+ char *elem_type, *elems, *ret;
+ guint32 num_elem = spec->data.array_data.num_elem;
+ guint32 param_num = spec->data.array_data.param_num;
+
+ elem_type = dis_stringify_native_type (spec->data.array_data.elem_type);
+ if (num_elem == -1 && param_num == -1)
+ elems = g_strdup ("");
+ else if ((param_num == -1) || (spec->data.array_data.elem_mult == 0))
+ elems = g_strdup_printf ("%d", num_elem);
+ else if ((num_elem == -1) || (num_elem == 0))
+ elems = g_strdup_printf ("+ %d", param_num);
+ else
+ elems = g_strdup_printf ("%d + %d", num_elem, param_num);
+
+ ret = g_strdup_printf (" marshal (%s[%s])", elem_type, elems);
+ g_free (elem_type);
+ g_free (elems);
+ return ret;
+ }
+ case MONO_NATIVE_SAFEARRAY: {
+ char *elem_type = NULL, *ret;
+
+ if (spec->data.safearray_data.elem_type != 0)
+ elem_type = dis_stringify_variant_type (spec->data.safearray_data.elem_type);
+ ret = g_strdup_printf (" marshal (safearray %s)", elem_type ? elem_type : "");
+
+ g_free (elem_type);
+ return ret;
+ }
+ default: {
+ char *native_type, *ret;
+ native_type = dis_stringify_native_type (spec->native);
+ ret = g_strdup_printf (" marshal (%s)", native_type);
+ g_free (native_type);
+ return ret;
+ }
+ }
+}
+
/**
* get_generic_param
* @m: metadata context
first = 0;
} else
g_string_append (result, ", ");
- sig = dis_stringify_object_with_class (m, *constr, FALSE);
+ sig = dis_stringify_type (m, &((*constr)->byval_arg), TRUE);
g_string_append (result, sig);
g_free (sig);
}
{
guint32 cols [MONO_METHOD_SIZE];
guint32 pcols [MONO_PARAM_SIZE];
- guint32 param_index = 0;
- const char *name = "";
+ guint32 param_index = 0, next_param_index = 0;
+ gboolean has_param_row;
+ const char *name = "", *method_name = "";
int free_method = 0;
char *retval, *esname;
char *type = NULL;
+ char *marshal_info = NULL, *ret_marshal_info = NULL;
char *gen_param = NULL;
GString *result = g_string_new ("");
+ GString *result_ret = g_string_new ("");
MonoGenericContainer *container = NULL;
- int i;
+ int i, start;
g_assert (method || methoddef_row);
mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD], methoddef_row -1, cols, MONO_METHOD_SIZE);
if (fully_qualified)
type = get_typedef (m, mono_metadata_typedef_from_method (m, methoddef_row));
- name = mono_metadata_string_heap (m, cols [MONO_METHOD_NAME]);
+ method_name = mono_metadata_string_heap (m, cols [MONO_METHOD_NAME]);
param_index = cols [MONO_METHOD_PARAMLIST];
if (!method) {
const char *sig = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]);
- container = mono_metadata_load_generic_params (m, MONO_TOKEN_METHOD_DEF | methoddef_row);
- if (container) {
- container->parent = context ? context->container : NULL;
- container->is_method = 1;
-
+ container = mono_metadata_load_generic_params (
+ m, MONO_TOKEN_METHOD_DEF | methoddef_row, context ? context->container : NULL);
+ if (container)
context = (MonoGenericContext *) container;
- }
mono_metadata_decode_blob_size (sig, &sig);
method = mono_metadata_parse_method_signature_full (m, context, methoddef_row, sig, &sig);
free_method = 1;
} else if (context)
container = context->container;
- gen_param = get_generic_param (m, container);
- }
-
- retval = dis_stringify_param (m, method->ret);
- if (method->hasthis)
- g_string_append (result, "instance ");
- g_string_append (result, map (method->call_convention, call_conv_type_map));
- g_string_sprintfa (result, " %s ", retval);
- if (type) {
- char *estype = get_escaped_name (type);
- g_string_sprintfa (result, "%s::", estype);
- g_free (estype);
- }
- esname = get_escaped_name (name);
- g_string_append (result, esname);
- g_free (esname);
- if (gen_param) {
- g_string_append (result, gen_param);
- g_free (gen_param);
- }
- g_string_append (result, " (");
- g_free (retval);
- for (i = 0; i < method->param_count; ++i) {
- if (param_index && param_index <= m->tables [MONO_TABLE_PARAM].rows) {
+
+ if (container && container->is_method)
+ gen_param = get_generic_param (m, container);
+
+ if (methoddef_row < m->tables [MONO_TABLE_METHOD].rows) {
+ mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD], methoddef_row, cols, MONO_METHOD_SIZE);
+ next_param_index = cols [MONO_METHOD_PARAMLIST];
+ } else {
+ next_param_index = m->tables [MONO_TABLE_PARAM].rows + 1;
+ }
+ }
+
+ start = method->hasthis ? 0 : 1;
+ for (i = 0; i < method->param_count + 1; ++i) {
+ marshal_info = NULL;
+ name = "";
+ has_param_row = param_index && param_index < next_param_index;
+
+ if (method->param_count == 0 && !has_param_row)
+ /* method has zero parameters, and no row for return val in the PARAM table */
+ continue;
+
+ if (has_param_row)
mono_metadata_decode_row (&m->tables [MONO_TABLE_PARAM], param_index - 1, pcols, MONO_PARAM_SIZE);
- name = mono_metadata_string_heap (m, pcols [MONO_PARAM_NAME]);
- method->params [i]->attrs = pcols [MONO_PARAM_FLAGS];
- param_index++;
+
+ if (has_param_row && i == pcols [MONO_PARAM_SEQUENCE]) {
+ if (i)
+ name = mono_metadata_string_heap (m, pcols [MONO_PARAM_NAME]);
+
+ if (pcols [MONO_PARAM_FLAGS] & PARAM_ATTRIBUTE_HAS_FIELD_MARSHAL) {
+ const char *tp;
+ MonoMarshalSpec *spec;
+ tp = mono_metadata_get_marshal_info (m, param_index - 1, FALSE);
+ g_assert (tp);
+ spec = mono_metadata_parse_marshal_spec (m, tp);
+
+ if (i)
+ marshal_info = dis_stringify_marshal_spec (spec);
+ else
+ ret_marshal_info = dis_stringify_marshal_spec (spec);
+ }
+ param_index ++;
} else {
- name = "";
+ if (i)
+ name = g_strdup_printf ("A_%i", i - start);
}
- if (i)
+
+ if (!i)
+ continue;
+
+ if (i > 1)
g_string_append (result, ", ");
- retval = dis_stringify_param (m, method->params [i]);
+
+ retval = dis_stringify_param (m, method->params [i - 1]);
+
esname = get_escaped_name (name);
- g_string_append_printf (result, "%s %s", retval, esname);
+ g_string_append_printf (result, "%s%s %s", retval, marshal_info ? marshal_info : "", esname);
g_free (retval);
g_free (esname);
+ g_free (marshal_info);
}
g_string_append (result, ") ");
+ retval = dis_stringify_param (m, method->ret);
+
+ if (method->hasthis)
+ g_string_append (result_ret, "instance ");
+ g_string_append (result_ret, map (method->call_convention, call_conv_type_map));
+ g_string_sprintfa (result_ret, " %s%s ", retval, ret_marshal_info ? ret_marshal_info :"");
+ g_free (ret_marshal_info);
+ if (type) {
+ char *estype = get_escaped_name (type);
+ g_string_sprintfa (result_ret, "%s::", estype);
+ g_free (estype);
+ }
+ esname = get_escaped_name (method_name);
+ g_string_append (result_ret, esname);
+ g_free (esname);
+ if (gen_param) {
+ g_string_append (result_ret, gen_param);
+ g_free (gen_param);
+ }
+ g_string_append (result_ret, " (");
+ g_free (retval);
+
+ g_string_prepend (result, result_ret->str);
+ g_string_free (result_ret, FALSE);
+
if (show_method_tokens && methoddef_row)
g_string_append_printf (result, " /* 0x%X */ ",
(methoddef_row >> MONO_TYPEORMETHOD_BITS) | MONO_TOKEN_METHOD_DEF);
}
static char *
-get_class_name (MonoClass *c)
+get_escaped_class_name (MonoClass *c)
{
+ char *result, *esname;
+
+ if (c->rank || c->byval_arg.type == MONO_TYPE_PTR)
+ g_assert (0);
+
+ esname = get_escaped_name (c->name);
+
if (c->nested_in){
- char *part_a = get_class_name (c->nested_in);
- char *result;
+ char *part_a = get_escaped_class_name (c->nested_in);
- result = g_strdup_printf ("%s/%s", part_a, c->name);
+ result = g_strdup_printf ("%s/%s", part_a, esname);
g_free (part_a);
- return result;
- }
- if (*c->name_space)
- return g_strdup_printf ("%s.%s", c->name_space, c->name);
+ } else if (*c->name_space)
+ result = g_strdup_printf ("%s.%s", c->name_space, esname);
else
- return g_strdup (c->name);
+ result = g_strdup (esname);
+
+ g_free (esname);
+ return result;
}
char *
-dis_stringify_object_with_class (MonoImage *m, MonoClass *c, gboolean prefix)
+dis_stringify_object_with_class (MonoImage *m, MonoClass *c, gboolean prefix, gboolean is_def)
{
/* FIXME: handle MONO_TYPE_OBJECT ... */
- const char *otype = c->byval_arg.type == MONO_TYPE_VALUETYPE ? "valuetype " : "class " ;
+ MonoType *type = &c->byval_arg;
+ const char *otype = type->type == MONO_TYPE_VALUETYPE ? "valuetype " : "class " ;
char *assemblyref = NULL, *result, *esname, *generic = NULL;
if (m != c->image) {
}
}
- result = get_class_name (c);
-
- esname = get_escaped_name (result);
- g_free (result);
+ esname = get_escaped_class_name (c);
if (c->generic_class) {
MonoGenericClass *gclass = c->generic_class;
int i;
for (i = 0; i < gclass->inst->type_argc; i++){
- char *t = dis_stringify_type (m, gclass->inst->type_argv [i]);
+ char *t = dis_stringify_type (m, gclass->inst->type_argv [i], is_def);
g_string_append (str, t);
if (i+1 != gclass->inst->type_argc)
}
static char *
-dis_stringify_object (MonoImage *m, MonoType *type)
+dis_stringify_object (MonoImage *m, MonoType *type, gboolean is_def)
{
MonoClass *c = mono_class_from_mono_type (type);
- return dis_stringify_object_with_class (m, c, TRUE);
+ return dis_stringify_object_with_class (m, c, TRUE, is_def);
}
char*
-dis_stringify_type (MonoImage *m, MonoType *type)
+dis_stringify_type (MonoImage *m, MonoType *type, gboolean is_def)
{
const char *pinned = "", *byref = "";
char *bare = NULL, *mods = NULL;
case MONO_TYPE_VALUETYPE:
case MONO_TYPE_CLASS:
- bare = dis_stringify_object (m, type);
+ bare = dis_stringify_object (m, type, is_def);
break;
case MONO_TYPE_FNPTR: {
char *child_type;
}
case MONO_TYPE_PTR: {
char *child_type;
- child_type = dis_stringify_type (m, type->data.type);
+ child_type = dis_stringify_type (m, type->data.type, is_def);
bare = g_strdup_printf ("%s*", child_type);
g_free (child_type);
}
case MONO_TYPE_SZARRAY: {
char *child_type;
- child_type = dis_stringify_type (m, &type->data.klass->byval_arg);
+ child_type = dis_stringify_type (m, &type->data.klass->byval_arg, is_def);
bare = g_strdup_printf ("%s[]", child_type);
g_free (child_type);
break;
}
case MONO_TYPE_ARRAY:
- bare = dis_stringify_array (m, type->data.array);
+ bare = dis_stringify_array (m, type->data.array, is_def);
break;
case MONO_TYPE_VOID:
bare = g_strdup ("void");
break;
case MONO_TYPE_MVAR:
- g_assert (type->data.generic_param->name);
- bare = g_strdup_printf ("!!%s", type->data.generic_param->name);
+ if (is_def) {
+ g_assert (type->data.generic_param->name);
+ bare = g_strdup_printf ("!!%s", type->data.generic_param->name);
+ } else
+ bare = g_strdup_printf ("!!%d", type->data.generic_param->num);
break;
case MONO_TYPE_VAR:
- g_assert (type->data.generic_param->name);
- bare = g_strdup_printf ("!%s", type->data.generic_param->name);
+ if (is_def) {
+ g_assert (type->data.generic_param->name);
+ bare = g_strdup_printf ("!%s", type->data.generic_param->name);
+ } else
+ bare = g_strdup_printf ("!%d", type->data.generic_param->num);
break;
case MONO_TYPE_GENERICINST: {
GString *str = g_string_new ("");
int i;
- char *generic_type = dis_stringify_type (m, type->data.generic_class->generic_type);
+ char *generic_type = dis_stringify_type (
+ m, &type->data.generic_class->container_class->byval_arg, is_def);
for (i = 0; i < type->data.generic_class->inst->type_argc; i++){
- char *t = dis_stringify_type (m, type->data.generic_class->inst->type_argv [i]);
+ char *t = dis_stringify_type (m, type->data.generic_class->inst->type_argv [i], is_def);
g_string_append (str, t);
if (i+1 != type->data.generic_class->inst->type_argc)
case MONO_TYPE_CLASS: {
guint32 token = mono_metadata_parse_typedef_or_ref (m, ptr, &ptr);
MonoClass *klass = mono_class_get (m, token);
- char *temp = dis_stringify_object_with_class (m, klass, TRUE);
+ char *temp = dis_stringify_object_with_class (m, klass, TRUE, FALSE);
if (show_tokens) {
*result = g_strdup_printf ("%s/*%08x*/", temp, token);
default:
t = mono_metadata_parse_type_full (m, context, MONO_PARSE_TYPE, 0, start, &ptr);
- *result = dis_stringify_type (m, t);
+ *result = dis_stringify_type (m, t, FALSE);
mono_metadata_free_type (t);
break;
}
}
if (*ptr == MONO_TYPE_TYPEDBYREF){
- g_string_append (str, "typedbyref");
+ g_string_append (str, "typedref");
ptr++;
} else if (*ptr == MONO_TYPE_VOID){
g_string_append (str, "void");
}
if (*ptr == MONO_TYPE_TYPEDBYREF){
- g_string_append (str, " typedbyref ");
+ g_string_append (str, " typedref ");
ptr++;
} else {
gboolean by_ref = 0;
get_escaped_name (const char *name)
{
const char *s;
+ char *tmp, *tmp2;
g_assert (key_table);
return g_strdup (name);
for (s = name; *s; s++) {
- if (isalnum (*s) || *s == '_' || *s == '$' || *s == '@' || *s == '?' || *s == '.' || *s == 0)
+ char *first, *result;
+
+ if (*s != '/')
+ continue;
+
+ first = g_strndup (name, s-name);
+ result = g_strdup_printf ("%s/%s", get_escaped_name (first), get_escaped_name (s+1));
+ g_free (first);
+
+ return result;
+ }
+
+ for (s = name; *s; s++) {
+ if (isalnum (*s) || *s == '_' || *s == '$' || *s == '@' ||
+ *s == '?' || *s == '.' || *s == 0 || *s == '!')
continue;
return g_strdup_printf ("'%s'", name);
{ FIELD_ATTRIBUTE_SPECIAL_NAME, "specialname " },
{ FIELD_ATTRIBUTE_PINVOKE_IMPL, "FIXME:pinvokeimpl " },
{ FIELD_ATTRIBUTE_RT_SPECIAL_NAME, "rtspecialname " },
- { FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL, "hasfieldmarshal " },
+ /*{ FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL, "hasfieldmarshal " },*/
{ 0, NULL }
};
switch (table){
case 0: /* TypeDef */
return (MonoGenericContext *) mono_metadata_load_generic_params (
- m, MONO_TOKEN_TYPE_DEF | idx);
+ m, MONO_TOKEN_TYPE_DEF | idx, NULL);
case 1: /* TypeRef */
return NULL;
return g_strdup ("TODO:MethodDef");
case 4: /* TypeSpec */
- return get_typespec (m, idx, context);
+ return get_typespec (m, idx, FALSE, context);
}
g_assert_not_reached ();
return NULL;
* Since there is no backpointer in the Field table, we have to scan
* the TypeDef table and locate the actual "owner" of the field
*/
-char *
+static char *
get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericContext *context)
{
int idx = mono_metadata_token_index (token);
mh = mono_get_method_full (m, token, NULL, context);
if (mh) {
- if (mh->signature->is_inflated)
+ if (mono_method_signature (mh)->is_inflated)
context = ((MonoMethodInflated *) mh)->context;
esname = get_escaped_name (mh->name);
- sig = dis_stringify_object_with_class (m, mh->klass, TRUE);
+ sig = dis_stringify_type (m, &mh->klass->byval_arg, TRUE);
if (show_tokens)
name = g_strdup_printf ("%s/*%08x*/::%s", sig, token, esname);
else
mh = mono_get_method (m, MONO_TOKEN_METHOD_DEF | idx, NULL);
if (mh) {
- sig = dis_stringify_object_with_class (m, mh->klass, TRUE);
+ sig = dis_stringify_type (m, &mh->klass->byval_arg, FALSE);
name = g_strdup_printf ("%s::%s", sig, mh->name);
g_free (sig);
} else
case MONO_TYPE_U4:
case MONO_TYPE_I4:
- return g_strdup_printf ("int32(%d)", read32 (ptr));
+ return g_strdup_printf ("int32(0x%08x)", read32 (ptr));
+ case MONO_TYPE_U8:
case MONO_TYPE_I8: {
guint32 low, high;
low = read32 (ptr);
high = read32 (ptr + 4);
return g_strdup_printf ("int64(0x%08x%08x)", high, low);
}
- case MONO_TYPE_U8: {
- guint32 low, high;
- low = read32 (ptr);
- high = read32 (ptr + 4);
- return g_strdup_printf ("0x%08x%08x", high, low);
- }
case MONO_TYPE_R4: {
float r;
readr4 (ptr, &r);
- return g_strdup_printf ("float32(%g)", (double) r);
- }
+ if (! isnormal (r))
+ return g_strdup_printf ("float32(0x%08x)", read32 (ptr));
+ else
+ return g_strdup_printf ("float32(%g)", r);
+ }
case MONO_TYPE_R8: {
double r;
readr8 (ptr, &r);
- return g_strdup_printf ("float64(%g)", r);
+ if (! isnormal (r)) {
+ guint32 low, high;
+ low = read32 (ptr);
+ high = read32 (ptr + 4);
+ return g_strdup_printf ("float64(0x%08x%08x)", high, low);
+ } else {
+ return g_strdup_printf ("float64(%g)", r);
+ }
}
case MONO_TYPE_STRING: {
gchar *str;
int i, j, tspaces = (len%16);
- GString *res = g_string_new ("bytearray (\n\t");
+ GString *res;
+
+ if (len == 0)
+ return g_strdup_printf ("\"\"");
+
+ res = g_string_new ("bytearray (\n\t");
for(i = 1; i <= len; ++i) {
g_string_append_printf(res, "%02x ", ptr[i-1]);
g_free (temp);
return result;
case MONO_TOKEN_TYPE_DEF:
- return get_typedef (m, idx);
+ temp = get_typedef (m, idx);
+ result = get_escaped_name (temp);
+ g_free (temp);
+ return result;
case MONO_TOKEN_TYPE_REF:
return get_typeref (m, idx);
case MONO_TOKEN_TYPE_SPEC:
- return get_typespec (m, idx, context);
+ return get_typespec (m, idx, TRUE, context);
case MONO_TOKEN_MEMBER_REF: {
guint32 cols [MONO_MEMBERREF_SIZE];
const char *sig;
result = g_strdup_printf ("field %s", temp);
g_free (temp);
return result;
- }
- else {
- g_error ("Do not know how to decode tokens of type 0x%08x", token);
+ } else {
+ temp = get_method (m, token, context);
+ result = g_strdup_printf ("method %s", temp);
+ g_free (temp);
+ return result;
}
break;
}
break;
case MONO_TOKEN_TYPE_SPEC:
- s = get_typespec (m, idx, context);
+ s = get_typespec (m, idx, FALSE, context);
break;
default:
g_hash_table_insert (key_table, (char *) "stored_object", GINT_TO_POINTER (TRUE));
g_hash_table_insert (key_table, (char *) "streamed_object", GINT_TO_POINTER (TRUE));
g_hash_table_insert (key_table, (char *) "stream", GINT_TO_POINTER (TRUE));
+ g_hash_table_insert (key_table, (char *) "strict", GINT_TO_POINTER (TRUE));
g_hash_table_insert (key_table, (char *) "string", GINT_TO_POINTER (TRUE));
g_hash_table_insert (key_table, (char *) "struct", GINT_TO_POINTER (TRUE));
g_hash_table_insert (key_table, (char *) "synchronized", GINT_TO_POINTER (TRUE));
g_hash_table_insert (key_table, (char *) "wchar", GINT_TO_POINTER (TRUE));
g_hash_table_insert (key_table, (char *) "winapi", GINT_TO_POINTER (TRUE));
g_hash_table_insert (key_table, (char *) "with", GINT_TO_POINTER (TRUE));
+ g_hash_table_insert (key_table, (char *) "xor", GINT_TO_POINTER (TRUE));
}
guint32