* Miguel de Icaza (miguel@ximian.com)
*
* (C) 2001 Ximian, Inc.
+ * Copyright 2012 Xamarin Inc
*/
#include <config.h>
#include <stdio.h>
extern gboolean substitute_with_mscorlib_p;
-static MonoGenericContext *
-get_memberref_context (MonoImage *m, guint32 mrp_token, MonoGenericContext *context);
+static MonoGenericContainer *
+get_memberref_container (MonoImage *m, guint32 mrp_token, MonoGenericContainer *container);
static char *
-get_memberref_parent (MonoImage *m, guint32 mrp_token, MonoGenericContext *context);
+get_memberref_parent (MonoImage *m, guint32 mrp_token, MonoGenericContainer *container);
static gboolean
cant_print_generic_param_name (MonoGenericParam *gparam);
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]);
}
}
* Returns the stringified representation of a TypeSpec signature (22.2.17)
*/
char *
-get_typespec (MonoImage *m, guint32 idx, gboolean is_def, MonoGenericContext *context)
+get_typespec (MonoImage *m, guint32 idx, gboolean is_def, MonoGenericContainer *container)
{
guint32 cols [MONO_TYPESPEC_SIZE];
const char *ptr;
if (*ptr == MONO_TYPE_VOID)
g_string_append (res, "void");
else {
- ptr = get_type (m, ptr, &s, is_def, context);
+ ptr = get_type (m, ptr, &s, is_def, container);
if (s)
g_string_append (res, s);
}
break;
case MONO_TYPE_FNPTR:
- sig = mono_metadata_parse_method_signature_full (m, context ? context->container : NULL, 0, ptr, &ptr);
+ sig = mono_metadata_parse_method_signature_full (m, container, 0, ptr, &ptr);
s = dis_stringify_function_ptr (m, sig);
g_string_append (res, "method ");
g_string_append (res, s);
break;
case MONO_TYPE_ARRAY:
- ptr = get_type (m, ptr, &s, is_def, context);
+ ptr = get_type (m, ptr, &s, is_def, container);
g_string_append (res, s);
g_free (s);
g_string_append_c (res, ' ');
g_string_append_c (res, ' ');
g_free (s);
}
- ptr = get_type (m, ptr, &s, is_def, context);
+ ptr = get_type (m, ptr, &s, is_def, container);
g_string_append (res, s);
g_string_append (res, "[]");
g_free (s);
break;
default:
- ptr = get_type (m, ptr - 1, &s, is_def, context);
+ ptr = get_type (m, ptr - 1, &s, is_def, container);
g_string_append (res, s);
g_free (s);
break;
* at (dor_token >> 2)
*/
char *
-get_typedef_or_ref (MonoImage *m, guint32 dor_token, MonoGenericContext *context)
+get_typedef_or_ref (MonoImage *m, guint32 dor_token, MonoGenericContainer *container)
{
char *temp = NULL, *s = NULL;
int table, idx;
break;
case 2: /* TypeSpec */
- s = get_typespec (m, idx, FALSE, context);
+ s = get_typespec (m, idx, FALSE, container);
break;
default:
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);
}
char*
dis_stringify_method_signature (MonoImage *m, MonoMethodSignature *method, int methoddef_row,
- MonoGenericContext *context, gboolean fully_qualified)
+ MonoGenericContainer *container, gboolean fully_qualified)
{
- return dis_stringify_method_signature_full (m, method, methoddef_row, context, fully_qualified, TRUE);
+ return dis_stringify_method_signature_full (m, method, methoddef_row, container, fully_qualified, TRUE);
}
/*
*/
char*
dis_stringify_method_signature_full (MonoImage *m, MonoMethodSignature *method, int methoddef_row,
- MonoGenericContext *context, gboolean fully_qualified, gboolean with_marshal_info)
+ MonoGenericContainer *container, gboolean fully_qualified, gboolean with_marshal_info)
{
guint32 cols [MONO_METHOD_SIZE];
guint32 pcols [MONO_PARAM_SIZE];
char *gen_param = NULL;
GString *result = g_string_new ("");
GString *result_ret = g_string_new ("");
- MonoGenericContainer *container = NULL;
int i, start;
g_assert (method || methoddef_row);
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 *sig = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]);
- container = mono_metadata_load_generic_params (
- m, MONO_TOKEN_METHOD_DEF | methoddef_row, context ? context->container : NULL);
- if (container) {
- mono_metadata_load_generic_param_constraints (
- m, MONO_TOKEN_METHOD_DEF | methoddef_row, container);
- context = (MonoGenericContext *) container;
- }
+ container = mono_metadata_load_generic_params (m, MONO_TOKEN_METHOD_DEF | methoddef_row, container);
+ if (container)
+ mono_metadata_load_generic_param_constraints (m, MONO_TOKEN_METHOD_DEF | methoddef_row, container);
mono_metadata_decode_blob_size (sig, &sig);
method = mono_metadata_parse_method_signature_full (m, container, methoddef_row, sig, &sig);
free_method = 1;
- } else if (context)
- container = context->container;
+ }
if (container && container->is_method)
gen_param = get_generic_param (m, container);
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);
}
* Returns: the new ptr to continue decoding
*/
const char *
-get_type (MonoImage *m, const char *ptr, char **result, gboolean is_def, MonoGenericContext *context)
+get_type (MonoImage *m, const char *ptr, char **result, gboolean is_def, MonoGenericContainer *container)
{
const char *start = ptr;
guint32 type;
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);
int count, i;
char *temp;
- ptr = get_type (m, ptr, &temp, is_def, context);
+ ptr = get_type (m, ptr, &temp, is_def, container);
g_string_append (str, temp);
g_free (temp);
for (i = 0; i < count; i++) {
if (i)
g_string_append (str, ",");
- ptr = get_type (m, ptr, &temp, is_def, context);
+ ptr = get_type (m, ptr, &temp, is_def, container);
g_string_append (str, temp);
}
}
default:
- t = mono_metadata_parse_type_full (m, context ? context->container : NULL, MONO_PARSE_TYPE, 0, start, &ptr);
- *result = dis_stringify_type (m, t, is_def);
- mono_metadata_free_type (t);
+ t = mono_metadata_parse_type_full (m, container, MONO_PARSE_TYPE, 0, start, &ptr);
+ 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;
}
* Returns a stringified representation of a FieldSig (22.2.4)
*/
char *
-get_field_signature (MonoImage *m, guint32 blob_signature, MonoGenericContext *context)
+get_field_signature (MonoImage *m, guint32 blob_signature, MonoGenericContainer *container)
{
char *allocated_modifier_string, *allocated_type_string;
const char *ptr = mono_metadata_blob_heap (m, blob_signature);
ptr++; len--;
ptr = get_custom_mod (m, ptr, &allocated_modifier_string);
- ptr = get_type (m, ptr, &allocated_type_string, FALSE, context);
+ ptr = get_type (m, ptr, &allocated_type_string, FALSE, container);
res = g_strdup_printf (
"%s%s",
* Returns: the new ptr to continue decoding.
*/
const char *
-get_ret_type (MonoImage *m, const char *ptr, char **ret_type, MonoGenericContext *context)
+get_ret_type (MonoImage *m, const char *ptr, char **ret_type, MonoGenericContainer *container)
{
GString *str = g_string_new ("");
char *mod = NULL;
ptr++;
}
- ptr = get_type (m, ptr, &allocated_type_string, FALSE, context);
+ ptr = get_type (m, ptr, &allocated_type_string, FALSE, container);
g_string_append (str, allocated_type_string);
if (has_byref)
g_string_append (str, "& ");
* Returns: the new ptr to continue decoding.
*/
const char *
-get_param (MonoImage *m, const char *ptr, char **retval, MonoGenericContext *context)
+get_param (MonoImage *m, const char *ptr, char **retval, MonoGenericContainer *container)
{
GString *str = g_string_new ("");
char *allocated_mod_string, *allocated_type_string;
ptr++;
by_ref = 1;
}
- ptr = get_type (m, ptr, &allocated_type_string, FALSE, context);
+ ptr = get_type (m, ptr, &allocated_type_string, FALSE, container);
g_string_append (str, allocated_type_string);
if (by_ref)
g_string_append_c (str, '&');
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);
}
* Returns a stringifed representation of a field ref
*/
char *
-get_fieldref_signature (MonoImage *m, int idx, MonoGenericContext *context)
+get_fieldref_signature (MonoImage *m, int idx, MonoGenericContainer *container)
{
guint32 cols [MONO_MEMBERREF_SIZE];
- MonoGenericContext *new_context;
+ MonoGenericContainer *new_container;
char *type, *esname;
char *sig;
char *full_sig;
mono_metadata_decode_row (&m->tables [MONO_TABLE_MEMBERREF],
idx - 1, cols, MONO_MEMBERREF_SIZE);
- new_context = get_memberref_context (m, cols [MONO_MEMBERREF_CLASS], context);
- sig = get_field_signature (m, cols [MONO_MEMBERREF_SIGNATURE], new_context);
+ new_container = get_memberref_container (m, cols [MONO_MEMBERREF_CLASS], container);
+ sig = get_field_signature (m, cols [MONO_MEMBERREF_SIGNATURE], new_container);
- type = get_memberref_parent (m, cols [MONO_MEMBERREF_CLASS], context);
+ type = get_memberref_parent (m, cols [MONO_MEMBERREF_CLASS], container);
esname = get_escaped_name (mono_metadata_string_heap (m, cols [MONO_MEMBERREF_NAME]));
full_sig = g_strdup_printf ("%s %s%s%s",
* the TypeDef table and locate the actual "owner" of the field
*/
char *
-get_field (MonoImage *m, guint32 token, MonoGenericContext *context)
+get_field (MonoImage *m, guint32 token, MonoGenericContainer *container)
{
int idx = mono_metadata_token_index (token);
guint32 cols [MONO_FIELD_SIZE];
* defined in another module/assembly, just like in get_method ()
*/
if (mono_metadata_token_code (token) == MONO_TOKEN_MEMBER_REF) {
- return get_fieldref_signature (m, idx, context);
+ return get_fieldref_signature (m, idx, container);
}
g_assert (mono_metadata_token_code (token) == MONO_TOKEN_FIELD_DEF);
mono_metadata_decode_row (&m->tables [MONO_TABLE_FIELD], idx - 1, cols, MONO_FIELD_SIZE);
- sig = get_field_signature (m, cols [MONO_FIELD_SIGNATURE], context);
+ sig = get_field_signature (m, cols [MONO_FIELD_SIGNATURE], container);
/*
* To locate the actual "container" for this field, we have to scan
* 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);
return res;
}
-static MonoGenericContext *
-get_memberref_context (MonoImage *m, guint32 mrp_token, MonoGenericContext *context)
+static MonoGenericContainer *
+get_memberref_container (MonoImage *m, guint32 mrp_token, MonoGenericContainer *container)
{
MonoClass *klass;
switch (table){
case 0: /* TypeDef */
- return (MonoGenericContext *) mono_metadata_load_generic_params (
- m, MONO_TOKEN_TYPE_DEF | idx, NULL);
+ return mono_metadata_load_generic_params (m, MONO_TOKEN_TYPE_DEF | idx, NULL);
case 1: /* TypeRef */
return NULL;
case 4: /* TypeSpec */
- klass = mono_class_get_full (m, MONO_TOKEN_TYPE_SPEC | idx, context);
+ klass = mono_class_get_full (m, MONO_TOKEN_TYPE_SPEC | idx, (MonoGenericContext *) container);
g_assert (klass);
- return klass->generic_class ? klass->generic_class->context : NULL;
+ return klass->generic_class ? klass->generic_class->container_class->generic_container : NULL;
}
g_assert_not_reached ();
return NULL;
}
static char *
-get_memberref_parent (MonoImage *m, guint32 mrp_token, MonoGenericContext *context)
+get_memberref_parent (MonoImage *m, guint32 mrp_token, MonoGenericContainer *container)
{
/*
* mrp_index is a MemberRefParent coded index
return g_strdup ("TODO:MethodDef");
case 4: /* TypeSpec */
- return get_typespec (m, idx, FALSE, context);
+ return get_typespec (m, idx, FALSE, container);
}
g_assert_not_reached ();
return NULL;
* the TypeDef table and locate the actual "owner" of the field
*/
static char *
-get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericContext *context)
+get_method_core (MonoImage *m, guint32 token, gboolean fullsig, MonoGenericContainer *container)
{
int idx = mono_metadata_token_index (token);
guint32 member_cols [MONO_MEMBERREF_SIZE], method_cols [MONO_METHOD_SIZE];
char *name;
MonoMethod *mh;
- MonoGenericContext *gc = context;
+ MonoGenericContainer *type_container = container;
- mh = mono_get_method_full (m, token, NULL, context);
+ 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)
- context = ((MonoMethodInflated *) mh)->context;
+ 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)
mono_metadata_decode_row (&m->tables [MONO_TABLE_MEMBERREF],
idx - 1, member_cols, MONO_MEMBERREF_SIZE);
if (!name) {
- char *parent = get_memberref_parent (m, member_cols [MONO_MEMBERREF_CLASS], context),
+ char *parent = get_memberref_parent (m, member_cols [MONO_MEMBERREF_CLASS], container);
name = g_strdup_printf ("%s%s%s",
parent ? parent : "",
parent ? "::" : "",
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);
mono_metadata_decode_row (&m->tables [MONO_TABLE_METHODSPEC],
idx - 1, member_cols, MONO_METHODSPEC_SIZE);
token = member_cols [MONO_METHODSPEC_METHOD];
- sig = get_methodspec (m, idx, token, name, gc);
+ sig = get_methodspec (m, idx, token, name, type_container);
break;
}
}
char *
-get_method (MonoImage *m, guint32 token, MonoGenericContext *context)
+get_method (MonoImage *m, guint32 token, MonoGenericContainer *container)
{
- return get_method_core (m, token, TRUE, context);
+ return get_method_core (m, token, TRUE, container);
}
/**
}
char *
-get_method_type_param (MonoImage *m, guint32 blob_signature, MonoGenericContext *context)
+get_method_type_param (MonoImage *m, guint32 blob_signature, MonoGenericContainer *container)
{
GString *res = g_string_new ("");
const char *ptr = mono_metadata_blob_heap (m, blob_signature);
for (i = 0; i < param_count; i++){
char *param = NULL;
- ptr = get_param (m, ptr, ¶m, context);
+ ptr = get_param (m, ptr, ¶m, container);
g_string_append (res, param);
if (i+1 != param_count)
g_string_append (res, ", ");
*/
char *
-get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name, MonoGenericContext *context)
+get_methodspec (MonoImage *m, int idx, guint32 token, const char *fancy_name, MonoGenericContainer *type_container)
{
GString *res = g_string_new ("");
guint32 member_cols [MONO_MEMBERREF_SIZE], method_cols [MONO_METHOD_SIZE];
const char *ptr;
guint32 sig = 0;
int param_count, cconv, i, gen_count = 0;
- MonoGenericContainer *container = NULL;
- MonoGenericContext *parent_context = context;
+ MonoGenericContainer *container;
MonoMethod *mh = NULL;
switch (token & MONO_METHODDEFORREF_MASK) {
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, parent_context);
+ mh = mono_get_method_full (m, method_dor_to_token (token), NULL, (MonoGenericContext *) type_container);
g_assert (mh);
- if ((container = mh->generic_container))
- context = (MonoGenericContext*) container;
+ container = mono_method_get_generic_container (mh);
+ if (!container)
+ container = type_container;
if (*ptr & 0x20){
if (*ptr & 0x40)
param_count = mono_metadata_decode_value (ptr, &ptr);
if (cconv != 0xa) {
char *allocated_ret_type;
- ptr = get_ret_type (m, ptr, &allocated_ret_type, context);
+ ptr = get_ret_type (m, ptr, &allocated_ret_type, container);
g_string_append (res, allocated_ret_type);
g_free (allocated_ret_type);
}
mono_metadata_decode_row (&m->tables [MONO_TABLE_METHODSPEC],
idx - 1, member_cols, MONO_METHODSPEC_SIZE);
token = member_cols [MONO_METHODSPEC_SIGNATURE];
- type_param = get_method_type_param (m, token, parent_context);
+ type_param = get_method_type_param (m, token, type_container);
g_string_append (res, type_param);
g_string_append (res, " (");
for (i = 0; i < param_count; i++){
char *param = NULL;
- ptr = get_param (m, ptr, ¶m, context);
+ ptr = get_param (m, ptr, ¶m, container);
g_string_append (res, param);
if (i+1 != param_count)
g_string_append (res, ", ");
char*
get_encoded_user_string_or_bytearray (const unsigned char *ptr, int len)
{
- unsigned char *res, *eres, *result;
+ char *res, *eres, *result;
int i;
res = g_malloc ((len >> 1) + 1);
char *
get_constant (MonoImage *m, MonoTypeEnum t, guint32 blob_index)
{
- const unsigned char *ptr = mono_metadata_blob_heap (m, blob_index);
+ const char *ptr = mono_metadata_blob_heap (m, blob_index);
int len;
- len = mono_metadata_decode_value (ptr, (const char**)&ptr);
+ len = mono_metadata_decode_value (ptr, &ptr);
switch (t){
case MONO_TYPE_BOOLEAN:
case MONO_TYPE_U1:
case MONO_TYPE_I1:
- return g_strdup_printf ("int8(0x%02x)", (int) (*ptr));
+ return g_strdup_printf ("int8(0x%02x)", (int) ((*ptr) & 0xFF));
break;
case MONO_TYPE_U2:
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);
#endif
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
}
}
case MONO_TYPE_STRING:
- return get_encoded_user_string_or_bytearray (ptr, len);
+ return get_encoded_user_string_or_bytearray ((const guchar*)ptr, len);
case MONO_TYPE_CLASS:
return g_strdup ("nullref");
* constant.
*/
char *
-get_token (MonoImage *m, guint32 token, MonoGenericContext *context)
+get_token (MonoImage *m, guint32 token, MonoGenericContainer *container)
{
char *temp, *result;
guint32 idx = mono_metadata_token_index (token);
switch (mono_metadata_token_code (token)){
case MONO_TOKEN_FIELD_DEF:
- temp = get_field (m, token, context);
+ temp = get_field (m, token, container);
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);
case MONO_TOKEN_TYPE_REF:
return get_typeref (m, idx);
case MONO_TOKEN_TYPE_SPEC:
- return get_typespec (m, idx, TRUE, context);
+ return get_typespec (m, idx, TRUE, container);
case MONO_TOKEN_MEMBER_REF: {
guint32 cols [MONO_MEMBERREF_SIZE];
const char *sig;
sig = mono_metadata_blob_heap (m, cols [MONO_MEMBERREF_SIGNATURE]);
mono_metadata_decode_blob_size (sig, &sig);
if (*sig == 0x6) { /* it's a field */
- temp = get_field (m, token, context);
+ temp = get_field (m, token, container);
result = g_strdup_printf ("field %s", temp);
g_free (temp);
return result;
} else {
- temp = get_method (m, token, context);
+ temp = get_method (m, token, container);
result = g_strdup_printf ("method %s", temp);
g_free (temp);
return result;
* at (token & 0xffffff)
*/
char *
-get_token_type (MonoImage *m, guint32 token, MonoGenericContext *context)
+get_token_type (MonoImage *m, guint32 token, MonoGenericContainer *container)
{
char *temp = NULL, *s = NULL;
int idx;
break;
case MONO_TOKEN_TYPE_SPEC:
- s = get_typespec (m, idx, FALSE, context);
+ s = get_typespec (m, idx, FALSE, container);
break;
default:
const unsigned char *guid;
char *result;
- guid = mono_metadata_guid_heap (m, guid_index);
+ guid = (const guchar*)mono_metadata_guid_heap (m, guid_index);
result = g_strdup_printf ("{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
guid [3], guid [2], guid [1], guid [0], guid [5], guid [4], guid [7], guid [6],
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));
}
char *
-get_method_override (MonoImage *m, guint32 token, MonoGenericContext *context)
+get_method_override (MonoImage *m, guint32 token, MonoGenericContainer *container)
{
MonoTableInfo *t = &m->tables [MONO_TABLE_METHODIMPL];
int i;
if (token == impl) {
MonoMethod *mh = NULL;
- mh = mono_get_method_full (m, decl, NULL, context);
- mh = mono_get_inflated_method (mh);
+ mh = mono_get_method_full (m, decl, NULL, (MonoGenericContext *) container);
if (mh && (mh->klass && (mh->klass->generic_class || mh->klass->generic_container))) {
char *meth_str;
char *ret;
- meth_str = get_method_core (m, decl, TRUE, context);
+ meth_str = get_method_core (m, decl, TRUE, container);
ret = g_strdup_printf ("method %s", meth_str);
g_free (meth_str);
return ret;
} else {
- return get_method_core (m, decl, FALSE, context);
+ return get_method_core (m, decl, FALSE, container);
}
}
}
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;
+}
+