MonoMethodSignature*
mono_metadata_parse_signature_full (MonoImage *image, MonoGenericContainer *generic_container, guint32 token)
{
+ MonoError error;
+ MonoMethodSignature *ret;
MonoTableInfo *tables = image->tables;
guint32 idx = mono_metadata_token_index (token);
guint32 sig;
ptr = mono_metadata_blob_heap (image, sig);
mono_metadata_decode_blob_size (ptr, &ptr);
- return mono_metadata_parse_method_signature_full (image, generic_container, 0, ptr, NULL);
+ ret = mono_metadata_parse_method_signature_full (image, generic_container, 0, ptr, NULL, &error);
+ if (!ret) {
+ mono_loader_set_error_from_mono_error (&error);
+ mono_error_cleanup (&error); /*FIXME don't swallow the error message*/
+ }
+ return ret;
}
/*
*/
MonoMethodSignature *
mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *container,
- int def, const char *ptr, const char **rptr)
+ int def, const char *ptr, const char **rptr, MonoError *error)
{
MonoMethodSignature *method;
int i, *pattrs = NULL;
guint32 gen_param_count = 0;
gboolean is_open = FALSE;
+ mono_error_init (error);
+
if (*ptr & 0x10)
gen_param_count = 1;
if (*ptr & 0x20)
if (!method->ret) {
mono_metadata_free_method_signature (method);
g_free (pattrs);
+ if (mono_loader_get_last_error ())
+ mono_error_set_from_loader_error (error);
+ else
+ mono_error_set_bad_image (error, m, "Could not parse return type signature");
return NULL;
}
is_open = mono_class_is_open_constructed_type (method->ret);
for (i = 0; i < method->param_count; ++i) {
if (*ptr == MONO_TYPE_SENTINEL) {
if (method->call_convention != MONO_CALL_VARARG || def) {
- g_warning ("found sentinel for methoddef or no vararg method 0x%08x on image %s", def, m->name);
+ g_assert (!mono_loader_get_last_error ());
+ mono_error_set_bad_image (error, m, "Found sentinel for methoddef or no vararg");
g_free (pattrs);
return NULL;
}
if (method->sentinelpos >= 0) {
- g_warning ("found sentinel twice in the same signature for method 0x%08x on image %s", def, m->name);
+ g_assert (!mono_loader_get_last_error ());
+ mono_error_set_bad_image (error, m, "Found sentinel twice in the same signature.");
g_free (pattrs);
return NULL;
}
}
method->params [i] = mono_metadata_parse_type_full (m, container, MONO_PARSE_PARAM, pattrs ? pattrs [i+1] : 0, ptr, &ptr);
if (!method->params [i]) {
+ if (mono_loader_get_last_error ())
+ mono_error_set_from_loader_error (error);
+ else
+ mono_error_set_bad_image (error, m, "Could not parse type argument %d on method signature", i);
mono_metadata_free_method_signature (method);
g_free (pattrs);
return NULL;
* Add signature to a cache and increase ref count...
*/
+ g_assert (!mono_loader_get_last_error ());
return method;
}
MonoMethodSignature *
mono_metadata_parse_method_signature (MonoImage *m, int def, const char *ptr, const char **rptr)
{
- return mono_metadata_parse_method_signature_full (m, NULL, def, ptr, rptr);
+ MonoError error;
+ MonoMethodSignature *ret;
+ ret = mono_metadata_parse_method_signature_full (m, NULL, def, ptr, rptr, &error);
+ if (!ret) {
+ mono_loader_set_error_from_mono_error (&error);
+ mono_error_cleanup (&error); /*FIXME don't swallow the error message*/
+ }
+ return ret;
}
/*
if (type == &type->data.klass->this_arg)
return type;
break;
+ default:
+ break;
}
return NULL;
/* NET 1.1 assemblies might encode string and object in a denormalized way.
* See #675464.
*/
- if (type_type == MONO_TYPE_CLASS && (class_type == MONO_TYPE_STRING || class_type == MONO_TYPE_OBJECT))
+ if (class_type == type_type)
+ return TRUE;
+
+ if (type_type == MONO_TYPE_CLASS)
+ return class_type == MONO_TYPE_STRING || class_type == MONO_TYPE_OBJECT;
+
+ g_assert (type_type == MONO_TYPE_VALUETYPE);
+ switch (class_type) {
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ case MONO_TYPE_R4:
+ case MONO_TYPE_R8:
+ case MONO_TYPE_I:
+ case MONO_TYPE_U:
return TRUE;
- return class_type == type_type;
+ default:
+ return FALSE;
+ }
}
/*
if (!type->data.type)
return FALSE;
break;
- case MONO_TYPE_FNPTR:
- type->data.method = mono_metadata_parse_method_signature_full (m, container, 0, ptr, &ptr);
- if (!type->data.method)
+ case MONO_TYPE_FNPTR: {
+ MonoError error;
+ type->data.method = mono_metadata_parse_method_signature_full (m, container, 0, ptr, &ptr, &error);
+ if (!type->data.method) {
+ mono_loader_set_error_from_mono_error (&error);
+ mono_error_cleanup (&error); /*FIXME don't swallow the error message*/
return FALSE;
+ }
break;
+ }
case MONO_TYPE_ARRAY:
type->data.array = mono_metadata_parse_array_internal (m, container, transient, ptr, &ptr);
if (!type->data.array)
case MONO_TYPE_ARRAY:
mono_metadata_free_array (type->data.array);
break;
+ default:
+ break;
}
g_free (type);
parse_section_data (MonoImage *m, int *num_clauses, const unsigned char *ptr)
{
unsigned char sect_data_flags;
- const unsigned char *sptr;
int is_fat;
guint32 sect_data_len;
MonoExceptionClause* clauses = NULL;
while (1) {
/* align on 32-bit boundary */
- sptr = ptr = dword_align (ptr);
+ ptr = dword_align (ptr);
sect_data_flags = *ptr;
ptr++;
sect_data_len = ptr [0];
++ptr;
}
- /*
- g_print ("flags: %02x, len: %d\n", sect_data_flags, sect_data_len);
- hex_dump (sptr, 0, sect_data_len+8);
- g_print ("\nheader: ");
- hex_dump (sptr-4, 0, 4);
- g_print ("\n");
- */
-
+
if (sect_data_flags & METHOD_HEADER_SECTION_EHTABLE) {
const unsigned char *p = dword_align (ptr);
int i;
guint32 local_var_sig_tok, max_stack, code_size, init_locals;
const unsigned char *code;
MonoExceptionClause* clauses = NULL;
- int hsize, num_clauses = 0;
+ int num_clauses = 0;
MonoTableInfo *t = &m->tables [MONO_TABLE_STANDALONESIG];
guint32 cols [MONO_STAND_ALONE_SIGNATURE_SIZE];
case METHOD_HEADER_FAT_FORMAT:
fat_flags = read16 (ptr);
ptr += 2;
- hsize = (fat_flags >> 12) & 0xf;
max_stack = read16 (ptr);
ptr += 2;
code_size = read32 (ptr);
clauses = parse_section_data (m, &num_clauses, (const unsigned char*)ptr);
if (local_var_sig_tok) {
const char *locals_ptr;
- int len=0, i, bsize;
+ int len=0, i;
locals_ptr = mono_metadata_blob_heap (m, cols [MONO_STAND_ALONE_SIGNATURE]);
- bsize = mono_metadata_decode_blob_size (locals_ptr, &locals_ptr);
+ mono_metadata_decode_blob_size (locals_ptr, &locals_ptr);
if (*locals_ptr != 0x07)
g_warning ("wrong signature for locals blob");
locals_ptr++;
* Returns: TRUE on success, FALSE on failure.
*/
gboolean
-mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, MonoClass ***interfaces, guint *count, gboolean heap_alloc_result, MonoGenericContext *context)
+mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, MonoClass ***interfaces, guint *count, gboolean heap_alloc_result, MonoGenericContext *context, MonoError *error)
{
MonoTableInfo *tdef = &meta->tables [MONO_TABLE_INTERFACEIMPL];
locator_t loc;
*interfaces = NULL;
*count = 0;
+ mono_error_init (error);
+
if (!tdef->base)
return TRUE;
pos = start;
while (pos < tdef->rows) {
- MonoError error;
MonoClass *iface;
mono_metadata_decode_row (tdef, pos, cols, MONO_INTERFACEIMPL_SIZE);
if (cols [MONO_INTERFACEIMPL_CLASS] != loc.idx)
break;
iface = mono_class_get_and_inflate_typespec_checked (
- meta, mono_metadata_token_from_dor (cols [MONO_INTERFACEIMPL_INTERFACE]), context, &error);
- if (iface == NULL) {
- mono_loader_set_error_from_mono_error (&error);
- mono_error_cleanup (&error); /* FIXME Don't swallow the error */
+ meta, mono_metadata_token_from_dor (cols [MONO_INTERFACEIMPL_INTERFACE]), context, error);
+ if (iface == NULL)
return FALSE;
- }
result [pos - start] = iface;
++pos;
}
MonoClass**
mono_metadata_interfaces_from_typedef (MonoImage *meta, guint32 index, guint *count)
{
- MonoClass **interfaces;
+ MonoError error;
+ MonoClass **interfaces = NULL;
gboolean rv;
- rv = mono_metadata_interfaces_from_typedef_full (meta, index, &interfaces, count, TRUE, NULL);
+ rv = mono_metadata_interfaces_from_typedef_full (meta, index, &interfaces, count, TRUE, NULL, &error);
+ g_assert (mono_error_ok (&error)); /* FIXME dont swallow the error */
if (rv)
return interfaces;
else
int
mono_type_size (MonoType *t, int *align)
{
+ MonoTypeEnum simple_type;
+
if (!t) {
*align = 1;
return 0;
return sizeof (gpointer);
}
- switch (t->type){
+ simple_type = t->type;
+ again:
+ switch (simple_type) {
case MONO_TYPE_VOID:
*align = 1;
return 0;
}
case MONO_TYPE_VAR:
case MONO_TYPE_MVAR:
- /* FIXME: Martin, this is wrong. */
- *align = MONO_ABI_ALIGNOF (gpointer);
- return sizeof (gpointer);
+ if (t->data.generic_param->gshared_constraint == 0 || t->data.generic_param->gshared_constraint == MONO_TYPE_VALUETYPE) {
+ *align = MONO_ABI_ALIGNOF (gpointer);
+ return sizeof (gpointer);
+ } else {
+ /* The gparam can only match types given by gshared_constraint */
+ simple_type = t->data.generic_param->gshared_constraint;
+ goto again;
+ }
default:
g_error ("mono_type_size: type 0x%02x unknown", t->type);
}
mono_type_stack_size_internal (MonoType *t, int *align, gboolean allow_open)
{
int tmp;
+ MonoTypeEnum simple_type;
#if SIZEOF_VOID_P == SIZEOF_REGISTER
int stack_slot_size = sizeof (gpointer);
int stack_slot_align = MONO_ABI_ALIGNOF (gpointer);
return stack_slot_size;
}
- switch (t->type){
+ simple_type = t->type;
+ again:
+ switch (simple_type) {
case MONO_TYPE_BOOLEAN:
case MONO_TYPE_CHAR:
case MONO_TYPE_I1:
case MONO_TYPE_VAR:
case MONO_TYPE_MVAR:
g_assert (allow_open);
- *align = stack_slot_align;
- return stack_slot_size;
+ if (t->data.generic_param->gshared_constraint == 0 || t->data.generic_param->gshared_constraint == MONO_TYPE_VALUETYPE) {
+ *align = stack_slot_align;
+ return stack_slot_size;
+ } else {
+ /* The gparam can only match types given by gshared_constraint */
+ simple_type = t->data.generic_param->gshared_constraint;
+ goto again;
+ }
case MONO_TYPE_TYPEDBYREF:
*align = stack_slot_align;
return stack_slot_size * 3;
case MONO_TYPE_VAR:
case MONO_TYPE_MVAR:
return ((hash << 5) - hash) ^ mono_metadata_generic_param_hash (t1->data.generic_param);
+ default:
+ return hash;
}
- return hash;
}
static guint
guint hash;
MonoGenericParamInfo *info;
- hash = (mono_generic_param_num (p) << 2) | p->serial;
+ hash = (mono_generic_param_num (p) << 2) | p->gshared_constraint;
info = mono_generic_param_info (p);
/* Can't hash on the owner klass/method, since those might not be set when this is called */
if (info)
return TRUE;
if (mono_generic_param_num (p1) != mono_generic_param_num (p2))
return FALSE;
- if (p1->serial != p2->serial)
+ if (p1->gshared_constraint != p2->gshared_constraint)
return FALSE;
/*
{
MonoError error;
MonoType *type = mono_type_create_from_typespec_checked (image, type_spec, &error);
- if (!type) {
- mono_loader_set_error_from_mono_error (&error);
- mono_error_cleanup (&error); /* FIXME don't swallow error*/
- }
+ if (!type)
+ g_error ("Could not create typespec %x due to %s", type_spec, mono_error_get_message (&error));
return type;
}
MonoTableInfo *t;
guint32 cols [MONO_TYPESPEC_SIZE];
const char *ptr;
- guint32 len;
MonoType *type, *type2;
mono_error_init (error);
return NULL;
}
- len = mono_metadata_decode_value (ptr, &ptr);
+ mono_metadata_decode_value (ptr, &ptr);
type = mono_metadata_parse_type_internal (image, NULL, MONO_PARSE_TYPE, 0, TRUE, ptr, &ptr);
if (!type) {
}
MonoMethod*
-method_from_method_def_or_ref (MonoImage *m, guint32 tok, MonoGenericContext *context)
+method_from_method_def_or_ref (MonoImage *m, guint32 tok, MonoGenericContext *context, MonoError *error)
{
+ MonoMethod *result = NULL;
guint32 idx = tok >> MONO_METHODDEFORREF_BITS;
+ mono_error_init (error);
+
switch (tok & MONO_METHODDEFORREF_MASK) {
case MONO_METHODDEFORREF_METHODDEF:
- return mono_get_method_full (m, MONO_TOKEN_METHOD_DEF | idx, NULL, context);
+ result = mono_get_method_checked (m, MONO_TOKEN_METHOD_DEF | idx, NULL, context, error);
+ break;
case MONO_METHODDEFORREF_METHODREF:
- return mono_get_method_full (m, MONO_TOKEN_MEMBER_REF | idx, NULL, context);
+ result = mono_get_method_checked (m, MONO_TOKEN_MEMBER_REF | idx, NULL, context, error);
+ break;
+ default:
+ mono_error_set_bad_image (error, m, "Invalid MethodDefOfRef token %x", tok);
}
- g_assert_not_reached ();
- return NULL;
+
+ return result;
}
/*
MonoMethod *method;
if (!mono_verifier_verify_methodimpl_row (image, start + i, &error)) {
- mono_error_cleanup (&error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
ok = FALSE;
break;
}
mono_metadata_decode_row (tdef, start + i, cols, MONO_METHODIMPL_SIZE);
method = method_from_method_def_or_ref (
- image, cols [MONO_METHODIMPL_DECLARATION], generic_context);
- if (method == NULL)
+ image, cols [MONO_METHODIMPL_DECLARATION], generic_context, &error);
+ if (method == NULL) {
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
ok = FALSE;
+ }
result [i * 2] = method;
method = method_from_method_def_or_ref (
- image, cols [MONO_METHODIMPL_BODY], generic_context);
- if (method == NULL)
+ image, cols [MONO_METHODIMPL_BODY], generic_context, &error);
+ if (method == NULL) {
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
ok = FALSE;
+ }
result [i * 2 + 1] = method;
}