*
* (C) 2001 Ximian, Inc.
* Copyright 2012 Xamarin Inc
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include <config.h>
#include <stdio.h>
#include <mono/utils/mono-compiler.h>
#include <mono/metadata/class.h>
#include <mono/metadata/marshal.h>
+#include <mono/metadata/metadata-internals.h>
extern gboolean substitute_with_mscorlib_p;
const char *
get_type (MonoImage *m, const char *ptr, char **result, gboolean is_def, MonoGenericContainer *container)
{
+ MonoError error;
const char *start = ptr;
guint32 type;
MonoType *t;
case MONO_TYPE_VALUETYPE:
case MONO_TYPE_CLASS: {
guint32 token = mono_metadata_parse_typedef_or_ref (m, ptr, &ptr);
- MonoClass *klass = mono_class_get (m, token);
+ MonoClass *klass = mono_class_get_checked (m, token, &error);
char *temp;
- if (klass)
+ if (klass) {
temp = dis_stringify_object_with_class (m, klass, TRUE, FALSE);
- else
- temp = g_strdup_printf ("<BROKEN CLASS token_%8x>", token);
+ } else {
+ temp = g_strdup_printf ("<BROKEN CLASS token_%8x due to %s>", token, mono_error_get_message (&error));
+ mono_error_cleanup (&error);
+ }
if (show_tokens) {
*result = g_strdup_printf ("%s/*%08x*/", temp, token);
}
default:
- t = mono_metadata_parse_type_full (m, container, 0, start, &ptr);
+ t = mono_metadata_parse_type_checked (m, container, 0, FALSE, start, &ptr, &error);
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, 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);
+ *result = g_strdup_printf ("Invalid type due to %s", mono_error_get_message (&error));
+ mono_error_cleanup (&error);
}
break;
static char *
get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericContainer *container)
{
+ MonoError error;
int idx = mono_metadata_token_index (token);
guint32 member_cols [MONO_MEMBERREF_SIZE], method_cols [MONO_METHOD_SIZE];
char *sig = NULL, *esname;
MonoMethod *mh;
MonoGenericContainer *type_container = container;
- mh = mono_get_method_full (m, token, NULL, (MonoGenericContext *) container);
+ mh = mono_get_method_checked (m, token, NULL, (MonoGenericContext *) container, &error);
if (mh) {
if (mono_method_signature (mh)->is_inflated)
container = mono_method_get_generic_container (((MonoMethodInflated *) mh)->declaring);
name = g_strdup_printf ("%s%s%s", sig ? sig : "", sig ? "::" : "", esname);
g_free (sig);
g_free (esname);
- } else
+ } else {
name = NULL;
+ mono_error_cleanup (&error);
+ }
switch (mono_metadata_token_code (token)){
case MONO_TOKEN_METHOD_DEF:
char *
get_methoddef (MonoImage *m, guint32 idx)
{
- guint32 cols [MONO_METHOD_SIZE];
+ MonoError error;
+ guint32 cols [MONO_METHOD_SIZE];
char *sig;
const char *name;
MonoMethod *mh;
- mh = mono_get_method (m, MONO_TOKEN_METHOD_DEF | idx, NULL);
+ mh = mono_get_method_checked (m, MONO_TOKEN_METHOD_DEF | idx, NULL, NULL, &error);
if (mh) {
sig = dis_stringify_type (m, &mh->klass->byval_arg, FALSE);
name = g_strdup_printf ("%s%s%s",
sig ? "::" : "",
mh->name);
g_free (sig);
- } else
- name = NULL;
- mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD],
- idx - 1, cols, MONO_METHOD_SIZE);
- sig = get_methodref_signature (m, cols [MONO_METHOD_SIGNATURE], name);
+ } else {
+ name = g_strdup_printf ("!bad-method-name!");
+ mono_error_cleanup (&error);
+ }
+ mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD],
+ idx - 1, cols, MONO_METHOD_SIZE);
+ sig = get_methodref_signature (m, cols [MONO_METHOD_SIGNATURE], name);
- return sig;
+ return sig;
}
char *
char *
get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name, MonoGenericContainer *type_container)
{
- GString *res = g_string_new ("");
+ MonoError error;
+ GString *res = g_string_new ("");
guint32 member_cols [MONO_MEMBERREF_SIZE], method_cols [MONO_METHOD_SIZE];
char *s, *type_param;
const char *ptr;
ptr = mono_metadata_blob_heap (m, sig);
mono_metadata_decode_value (ptr, &ptr);
- mh = mono_get_method_full (m, method_dor_to_token (token), NULL, (MonoGenericContext *) type_container);
- g_assert (mh);
+ mh = mono_get_method_checked (m, method_dor_to_token (token), NULL, (MonoGenericContext *) type_container, &error);
+ if (!mh) {
+ g_string_append_printf (res, "Could not decode method token 0x%x due to %s", token, mono_error_get_message (&error));
+ mono_error_cleanup (&error);
+ return g_string_free (res, FALSE);
+ }
+
container = mono_method_get_generic_container (mh);
if (!container)
container = type_container;
char *res, *eres, *result;
int i;
- res = g_malloc ((len >> 1) + 1);
+ res = (char *)g_malloc ((len >> 1) + 1);
/*
* I should really use some kind of libunicode here
decl = method_dor_to_token (cols [MONO_METHODIMPL_DECLARATION]);
if (token == impl) {
+ MonoError error;
MonoMethod *mh = NULL;
- mh = mono_get_method_full (m, decl, NULL, (MonoGenericContext *) container);
+ mh = mono_get_method_checked (m, decl, NULL, (MonoGenericContext *) container, &error);
if (mh && (mh->klass && (mh->klass->generic_class || mh->klass->generic_container))) {
char *meth_str;
g_free (meth_str);
return ret;
} else {
- return get_method_core (m, decl, FALSE, container);
+ char *meth_str = get_method_core (m, decl, FALSE, container);
+ char *ret = g_strdup_printf ("Could not decode method override %s due to %s", meth_str, mono_error_get_message (&error));
+
+ mono_error_cleanup (&error);
+ g_free (meth_str);
+ return ret;
}
}
}
for (i = 0; i < container->type_argc; i++) {
MonoGenericParam *param = mono_generic_container_get_param (container, i);
- if ((p = g_hash_table_lookup (table, mono_generic_param_info (param)->name)))
+ if ((p = (gpointer *)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*)mono_generic_param_info (param)->name, GUINT_TO_POINTER (i + 1));
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)));
+ g_hash_table_lookup (mono_generic_params_with_ambiguous_names, gparam)) || !mono_generic_param_info (gparam));
}