* Miguel de Icaza (miguel@ximian.com)
*
* (C) 2001 Ximian, Inc.
+ * Copyright 2012 Xamarin Inc
*/
#include <config.h>
#include <stdio.h>
if (i)
g_string_append_c (res, ',');
if (i < num_lo_bounds)
- g_string_sprintfa (res, "%d...", lo_bounds [i]);
+ g_string_append_printf (res, "%d...", lo_bounds [i]);
if (i < num_sizes) {
if (i < num_lo_bounds)
- g_string_sprintfa (res, "%d", lo_bounds [i] + sizes [i] - 1);
+ g_string_append_printf (res, "%d", lo_bounds [i] + sizes [i] - 1);
else
- g_string_sprintfa (res, "%d", sizes [i]);
+ g_string_append_printf (res, "%d", sizes [i]);
}
}
for (i = 0; i < n; ++i) {
char *tok = dis_stringify_token (m, mod[i].token);
if (i > 0)
- g_string_sprintfa (s, " ");
- g_string_sprintfa (s, " %s (%s)", mod[i].required ? "modreq": "modopt", tok);
+ g_string_append_printf (s, " ");
+ g_string_append_printf (s, " %s (%s)", mod[i].required ? "modreq": "modopt", tok);
g_free (tok);
}
g_string_append_c (s, ' ');
g_string_append_c (result, '<');
for (i = 0; i < container->type_argc; i++) {
- MonoGenericParam *param = &container->type_params [i];
+ MonoGenericParam *param = mono_generic_container_get_param (container, i);
+ MonoGenericParamInfo *param_info = mono_generic_param_info (param);
MonoClass **constr;
int first = 1;
guint16 flags;
if (i > 0)
g_string_append (result, ",");
+
+ flags = param_info->flags & GENERIC_PARAMETER_ATTRIBUTE_VARIANCE_MASK;
+ if ((flags & GENERIC_PARAMETER_ATTRIBUTE_COVARIANT) == GENERIC_PARAMETER_ATTRIBUTE_COVARIANT)
+ g_string_append (result, "+ ");
+ if ((flags & GENERIC_PARAMETER_ATTRIBUTE_CONTRAVARIANT) == GENERIC_PARAMETER_ATTRIBUTE_CONTRAVARIANT)
+ g_string_append (result, "- ");
- flags = param->flags & GENERIC_PARAMETER_ATTRIBUTE_SPECIAL_CONSTRAINTS_MASK;
+ flags = param_info->flags & GENERIC_PARAMETER_ATTRIBUTE_SPECIAL_CONSTRAINTS_MASK;
if ((flags & GENERIC_PARAMETER_ATTRIBUTE_REFERENCE_TYPE_CONSTRAINT) == GENERIC_PARAMETER_ATTRIBUTE_REFERENCE_TYPE_CONSTRAINT)
g_string_append (result, "class ");
if ((flags & GENERIC_PARAMETER_ATTRIBUTE_VALUE_TYPE_CONSTRAINT) == GENERIC_PARAMETER_ATTRIBUTE_VALUE_TYPE_CONSTRAINT)
if ((flags & GENERIC_PARAMETER_ATTRIBUTE_CONSTRUCTOR_CONSTRAINT) == GENERIC_PARAMETER_ATTRIBUTE_CONSTRUCTOR_CONSTRAINT)
g_string_append (result, ".ctor ");
- for (constr = param->constraints; constr && *constr; constr++) {
+ for (constr = param_info->constraints; constr && *constr; constr++) {
char *sig;
if (first) {
if (!first)
g_string_append (result, ") ");
- esname = get_escaped_name (param->name);
+ esname = get_escaped_name (mono_generic_param_info (param)->name);
g_string_append (result, esname);
g_free (esname);
}
if (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));
+ if (fully_qualified) {
+ guint32 type_idx = mono_metadata_typedef_from_method (m, methoddef_row);
+ if (type_idx)
+ type = get_typedef (m, type_idx);
+ else
+ type = g_strdup ("<invalid>");
+ }
method_name = mono_metadata_string_heap (m, cols [MONO_METHOD_NAME]);
param_index = cols [MONO_METHOD_PARAMLIST];
if (!method) {
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);
+ if (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);
+ } else {
+ if (i)
+ marshal_info = g_strdup ("(missing)");
+ else
+ ret_marshal_info = g_strdup ("(missing)");
+ }
}
param_index ++;
} else {
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_string_append_printf (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_string_append_printf (result_ret, "%s::", estype);
g_free (estype);
g_free (type);
}
g_string_append (result, map (method->call_convention, call_conv_type_map));
retval = dis_stringify_param (m, method->ret);
- g_string_sprintfa (result, " %s ", retval);
+ g_string_append_printf (result, " %s ", retval);
g_free (retval);
g_string_append (result, " *(");
if (c->generic_class) {
MonoGenericClass *gclass = c->generic_class;
+ MonoGenericInst *inst = gclass->context.class_inst;
GString *str = g_string_new ("");
int i;
- for (i = 0; i < gclass->inst->type_argc; i++){
- char *t = dis_stringify_type (m, gclass->inst->type_argv [i], is_def);
+ for (i = 0; i < inst->type_argc; i++){
+ char *t = dis_stringify_type (m, inst->type_argv [i], is_def);
g_string_append (str, t);
- if (i+1 != gclass->inst->type_argc)
+ if (i+1 != inst->type_argc)
g_string_append (str, ", ");
g_free (t);
}
break;
case MONO_TYPE_MVAR:
if (is_def && !cant_print_generic_param_name (type->data.generic_param))
- bare = g_strdup_printf ("!!%s", get_escaped_name (type->data.generic_param->name));
+ bare = g_strdup_printf ("!!%s", get_escaped_name (mono_generic_param_info (type->data.generic_param)->name));
else
- bare = g_strdup_printf ("!!%d", type->data.generic_param->num);
+ bare = g_strdup_printf ("!!%d", mono_type_get_generic_param_num (type));
break;
case MONO_TYPE_VAR:
if (is_def && !cant_print_generic_param_name (type->data.generic_param))
- bare = g_strdup_printf ("!%s", get_escaped_name (type->data.generic_param->name));
+ bare = g_strdup_printf ("!%s", get_escaped_name (mono_generic_param_info (type->data.generic_param)->name));
else
- bare = g_strdup_printf ("!%d", type->data.generic_param->num);
+ bare = g_strdup_printf ("!%d", mono_type_get_generic_param_num (type));
break;
case MONO_TYPE_GENERICINST: {
GString *str = g_string_new ("");
+ MonoGenericInst *inst;
int i;
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], is_def);
+ inst = type->data.generic_class->context.class_inst;
+ for (i = 0; i < inst->type_argc; i++){
+ char *t = dis_stringify_type (m, inst->type_argv [i], is_def);
g_string_append (str, t);
- if (i+1 != type->data.generic_class->inst->type_argc)
+ if (i+1 != inst->type_argc)
g_string_append (str, ", ");
g_free (t);
}
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, FALSE);
+ char *temp;
+ if (klass)
+ temp = dis_stringify_object_with_class (m, klass, TRUE, FALSE);
+ else
+ temp = g_strdup_printf ("<BROKEN CLASS token_%8x>", token);
if (show_tokens) {
*result = g_strdup_printf ("%s/*%08x*/", temp, token);
default:
t = mono_metadata_parse_type_full (m, container, MONO_PARSE_TYPE, 0, start, &ptr);
- *result = dis_stringify_type (m, t, is_def);
- mono_metadata_free_type (t);
+ if (t) {
+ *result = dis_stringify_type (m, t, is_def);
+ } else {
+ GString *err = g_string_new ("@!#$<InvalidType>$#!@");
+ if (container)
+ t = mono_metadata_parse_type_full (m, NULL, MONO_PARSE_TYPE, 0, start, &ptr);
+ if (t) {
+ char *name = dis_stringify_type (m, t, is_def);
+ g_warning ("Encountered a generic type inappropriate for its context");
+ g_string_append (err, " // ");
+ g_string_append (err, name);
+ g_free (name);
+ } else {
+ g_warning ("Encountered an invalid type");
+ }
+ *result = g_string_free (err, FALSE);
+ }
+
break;
}
for (s = name; *s; s++) {
if (isalnum (*s) || *s == '_' || *s == '$' || *s == '@' ||
- *s == '?' || *s == '.' || *s == 0 || *s == '!' || *s == '`')
+ *s == '?' || (*s == '.' && s != name) || *s == 0 || *s == '!' || *s == '`')
continue;
esc = str_escape (name, "'\\");
{ FIELD_ATTRIBUTE_SPECIAL_NAME, "specialname " },
{ FIELD_ATTRIBUTE_PINVOKE_IMPL, "FIXME:pinvokeimpl " },
{ FIELD_ATTRIBUTE_RT_SPECIAL_NAME, "rtspecialname " },
- /*{ FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL, "hasfieldmarshal " },*/
+
+ /* This is set when a MarshalAs attribute is seen. FIXME: round-trip? */
+ { FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL, "" },
+
+ /* This seems to be set if LITERAL is set. FIXME: round-trip? */
+ { FIELD_ATTRIBUTE_HAS_DEFAULT, "" },
+
+ /* This seems to be set on compiler-generated array initializer fields. FIXME: round-trip? */
+ { FIELD_ATTRIBUTE_HAS_FIELD_RVA, "" },
{ 0, NULL }
};
{
char buffer [1024];
int access = f & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK;
+ int rest = f & ~access;
buffer [0] = 0;
strcat (buffer, map (access, field_access_map));
- strcat (buffer, flags (f, field_flags_map));
+ strcat (buffer, flags (rest, field_flags_map));
return g_strdup (buffer);
}
* the TypeDef table. LAME!
*/
type_idx = mono_metadata_typedef_from_field (m, idx);
+ if (!type_idx) {
+ res = g_strdup_printf ("<invalid> %s", sig);
+ g_free (sig);
+ return res;
+ }
type = get_typedef (m, type_idx);
estype = get_escaped_name (type);
mh = mono_get_method_full (m, token, NULL, (MonoGenericContext *) container);
if (mh) {
- mh = mono_get_inflated_method (mh);
if (mono_method_signature (mh)->is_inflated)
- container = ((MonoMethodInflated *) mh)->declaring->generic_container;
+ container = mono_method_get_generic_container (((MonoMethodInflated *) mh)->declaring);
esname = get_escaped_name (mh->name);
sig = dis_stringify_type (m, &mh->klass->byval_arg, TRUE);
if (show_tokens)
if (mh) {
int arity = 0;
- if (mh->generic_container)
- arity = mh->generic_container->type_argc;
+ if (mh->is_generic)
+ arity = mono_method_get_generic_container (mh)->type_argc;
else
- if (mh->is_inflated && ((MonoMethodInflated *)mh)->declaring->generic_container)
- arity = ((MonoMethodInflated*) mh)->declaring->generic_container->type_argc;
+ if (mh->is_inflated && ((MonoMethodInflated *)mh)->declaring->is_generic)
+ arity = mono_method_get_generic_container (((MonoMethodInflated*) mh)->declaring)->type_argc;
if (arity > 0) {
char *str = g_strdup_printf ("%s <[%d]>", name, arity);
mh = mono_get_method_full (m, method_dor_to_token (token), NULL, (MonoGenericContext *) type_container);
g_assert (mh);
- container = mh->generic_container;
+ container = mono_method_get_generic_container (mh);
if (!container)
container = type_container;
readr4 (ptr, &r);
/* Crazy solaris systems doesn't have isnormal */
-#ifdef HAVE_FINITE
- normal = finite (r);
+#ifdef HAVE_ISFINITE
+ normal = isfinite (r);
#else
- normal = isnormal (r);
+ normal = !dis_isinf (r) && !dis_isnan (r);
#endif
if (!normal) {
return g_strdup_printf ("float32(0x%08x)", read32 (ptr));
readr8 (ptr, &r);
/* Crazy solaris systems doesn't have isnormal */
-#ifdef HAVE_FINITE
- normal = finite (r);
+#ifdef HAVE_ISFINITE
+ normal = isfinite (r);
#else
normal = isnormal (r);
#endif
result = g_strdup_printf ("field %s", temp);
g_free (temp);
return result;
+ case MONO_TOKEN_METHOD_DEF:
+ case MONO_TOKEN_METHOD_SPEC:
+ temp = get_method (m, token, container);
+ result = g_strdup_printf ("method %s", temp);
+ g_free (temp);
+ return result;
case MONO_TOKEN_TYPE_DEF:
temp = get_typedef (m, idx);
result = get_escaped_name (temp);
len = mono_metadata_decode_value (val, &val);
attr = g_string_new (".custom ");
dump = data_dump (val, len, "\t\t");
- g_string_sprintfa (attr, "%s = %s", method, dump);
+ g_string_append_printf (attr, "%s = %s", method, dump);
g_free (dump);
list = g_list_append (list, attr->str);
g_string_free (attr, FALSE);
g_hash_table_insert (key_table, (char *) "ldvirtftn", GINT_TO_POINTER (TRUE));
g_hash_table_insert (key_table, (char *) "leave", GINT_TO_POINTER (TRUE));
g_hash_table_insert (key_table, (char *) "leave.s", GINT_TO_POINTER (TRUE));
+ g_hash_table_insert (key_table, (char *) "legacy", GINT_TO_POINTER (TRUE));
g_hash_table_insert (key_table, (char *) "linkcheck", GINT_TO_POINTER (TRUE));
g_hash_table_insert (key_table, (char *) "literal", GINT_TO_POINTER (TRUE));
g_hash_table_insert (key_table, (char *) "localloc", GINT_TO_POINTER (TRUE));
if (token == impl) {
MonoMethod *mh = NULL;
mh = mono_get_method_full (m, decl, NULL, (MonoGenericContext *) container);
- mh = mono_get_inflated_method (mh);
if (mh && (mh->klass && (mh->klass->generic_class || mh->klass->generic_container))) {
char *meth_str;
table = g_hash_table_new (g_str_hash, g_str_equal);
for (i = 0; i < container->type_argc; i++) {
- MonoGenericParam *param = &container->type_params [i];
+ MonoGenericParam *param = mono_generic_container_get_param (container, i);
- if ((p = g_hash_table_lookup (table, param->name)))
+ if ((p = g_hash_table_lookup (table, mono_generic_param_info (param)->name)))
dup_list = g_slist_prepend (g_slist_prepend (dup_list, GUINT_TO_POINTER (i + 1)), p);
else
- g_hash_table_insert (table, (char*)param->name, GUINT_TO_POINTER (i + 1));
+ g_hash_table_insert (table, (char*)mono_generic_param_info (param)->name, GUINT_TO_POINTER (i + 1));
}
if (dup_list) {
for (l = dup_list; l; l = l->next) {
int param = GPOINTER_TO_UINT (l->data);
g_hash_table_insert (mono_generic_params_with_ambiguous_names,
- &container->type_params [param-1],
- &container->type_params [param-1]);
+ mono_generic_container_get_param (container, param-1),
+ mono_generic_container_get_param (container, param-1));
}
g_slist_free (dup_list);
}
static gboolean
cant_print_generic_param_name (MonoGenericParam *gparam)
{
+ MonoGenericContainer *container;
g_assert (gparam);
- check_ambiguous_genparams (gparam->owner);
- return (!gparam->owner || (mono_generic_params_with_ambiguous_names &&
+ container = mono_generic_param_owner (gparam);
+ check_ambiguous_genparams (container);
+ return (!container || (mono_generic_params_with_ambiguous_names &&
g_hash_table_lookup (mono_generic_params_with_ambiguous_names, gparam)));
}
+static dis_map_t method_impl_map [] = {
+ { METHOD_IMPL_ATTRIBUTE_IL, "cil " },
+ { METHOD_IMPL_ATTRIBUTE_NATIVE, "native " },
+ { METHOD_IMPL_ATTRIBUTE_OPTIL, "optil " },
+ { METHOD_IMPL_ATTRIBUTE_RUNTIME, "runtime " },
+ { 0, NULL }
+};
+
+static dis_map_t managed_type_map [] = {
+ { METHOD_IMPL_ATTRIBUTE_UNMANAGED, "unmanaged " },
+ { METHOD_IMPL_ATTRIBUTE_MANAGED, "managed " },
+ { 0, NULL }
+};
+
+static dis_map_t managed_impl_flags [] = {
+ { METHOD_IMPL_ATTRIBUTE_FORWARD_REF, "fwdref " },
+ { METHOD_IMPL_ATTRIBUTE_PRESERVE_SIG, "preservesig " },
+ { METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL, "internalcall " },
+ { METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED, "synchronized " },
+ { METHOD_IMPL_ATTRIBUTE_NOINLINING, "noinlining " },
+ { METHOD_IMPL_ATTRIBUTE_NOOPTIMIZATION, "nooptimization " },
+ { METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING, "agressive-inlining" },
+ { 0, NULL }
+};
+
+char *
+get_method_impl_flags (guint32 f)
+{
+ GString *str = g_string_new ("");
+ char *s;
+ int code_type = f & METHOD_IMPL_ATTRIBUTE_CODE_TYPE_MASK;
+ int managed_type = f & METHOD_IMPL_ATTRIBUTE_MANAGED_MASK;
+ int rest = f & ~(code_type | managed_type);
+
+ g_string_append (str, map (code_type, method_impl_map));
+ g_string_append (str, map (managed_type, managed_type_map));
+ g_string_append (str, flags (rest, managed_impl_flags));
+
+ s = str->str;
+ g_string_free (str, FALSE);
+ return s;
+}
+