* TODO:
* This should keep track of the assembly versions that we are loading.
*
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include <config.h>
#include <glib.h>
MonoClass *handle_class;
*retklass = NULL;
- result = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, TRUE, &handle_class, context);
+ MonoError inner_error;
+ result = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, TRUE, &handle_class, context, &inner_error);
+ mono_error_cleanup (&inner_error);
// This checks the memberref type as well
if (!result || handle_class != mono_defaults.fieldhandle_class) {
mono_error_set_bad_image (error, image, "Bad field token 0x%08x", token);
static MonoMethodHeader*
inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context, MonoError *error)
{
- MonoMethodHeader *res;
- int i;
- res = (MonoMethodHeader *)g_malloc0 (MONO_SIZEOF_METHOD_HEADER + sizeof (gpointer) * header->num_locals);
+ size_t locals_size = sizeof (gpointer) * header->num_locals;
+ size_t clauses_size = header->num_clauses * sizeof (MonoExceptionClause);
+ size_t header_size = MONO_SIZEOF_METHOD_HEADER + locals_size + clauses_size;
+ MonoMethodHeader *res = (MonoMethodHeader *)g_malloc0 (header_size);
+ res->num_locals = header->num_locals;
+ res->clauses = (MonoExceptionClause *) &res->locals [res->num_locals] ;
+ memcpy (res->clauses, header->clauses, clauses_size);
+
res->code = header->code;
res->code_size = header->code_size;
res->max_stack = header->max_stack;
res->num_clauses = header->num_clauses;
res->init_locals = header->init_locals;
- res->num_locals = header->num_locals;
- res->clauses = header->clauses;
+
+ res->is_transient = TRUE;
mono_error_init (error);
- for (i = 0; i < header->num_locals; ++i) {
+ for (int i = 0; i < header->num_locals; ++i) {
res->locals [i] = mono_class_inflate_generic_type_checked (header->locals [i], context, error);
if (!is_ok (error))
goto fail;
}
if (res->num_clauses) {
- res->clauses = (MonoExceptionClause *)g_memdup (header->clauses, sizeof (MonoExceptionClause) * res->num_clauses);
- for (i = 0; i < header->num_clauses; ++i) {
+ for (int i = 0; i < header->num_clauses; ++i) {
MonoExceptionClause *clause = &res->clauses [i];
if (clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
continue;
{
MonoError error;
MonoMethodSignature *res = mono_method_get_signature_checked (method, image, token, context, &error);
- g_assert (mono_error_ok (&error));
+ mono_error_cleanup (&error);
return res;
}
if (image_is_dynamic (image)) {
MonoClass *handle_class;
- result = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, TRUE, &handle_class, context);
+ result = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, TRUE, &handle_class, context, error);
+ mono_error_assert_ok (error);
mono_loader_assert_no_error ();
// This checks the memberref type as well
}
MonoMethodHeader*
-mono_method_get_header (MonoMethod *method)
+mono_method_get_header_checked (MonoMethod *method, MonoError *error)
{
- MonoError error;
int idx;
guint32 rva;
MonoImage* img;
gpointer loc;
- MonoMethodHeader *header;
MonoGenericContainer *container;
- if ((method->flags & METHOD_ATTRIBUTE_ABSTRACT) || (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
- return NULL;
-
+ mono_error_init (error);
img = method->klass->image;
+ if ((method->flags & METHOD_ATTRIBUTE_ABSTRACT) || (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) {
+ mono_error_set_bad_image (error, img, "Method has no body");
+ return NULL;
+ }
+
if (method->is_inflated) {
MonoMethodInflated *imethod = (MonoMethodInflated *) method;
MonoMethodHeader *header, *iheader;
- header = mono_method_get_header (imethod->declaring);
+ header = mono_method_get_header_checked (imethod->declaring, error);
if (!header)
return NULL;
- iheader = inflate_generic_header (header, mono_method_get_context (method), &error);
+ iheader = inflate_generic_header (header, mono_method_get_context (method), error);
mono_metadata_free_mh (header);
if (!iheader) {
- mono_loader_set_error_from_mono_error (&error);
return NULL;
}
- mono_image_lock (img);
-
- if (imethod->header) {
- mono_metadata_free_mh (iheader);
- mono_image_unlock (img);
- return imethod->header;
- }
-
- mono_memory_barrier ();
- imethod->header = iheader;
-
- mono_image_unlock (img);
-
- return imethod->header;
+ return iheader;
}
if (method->wrapper_type != MONO_WRAPPER_NONE || method->sre_method) {
idx = mono_metadata_token_index (method->token);
rva = mono_metadata_decode_row_col (&img->tables [MONO_TABLE_METHOD], idx - 1, MONO_METHOD_RVA);
- if (!mono_verifier_verify_method_header (img, rva, NULL))
+ if (!mono_verifier_verify_method_header (img, rva, NULL)) {
+ mono_error_set_bad_image (error, img, "Invalid method header, failed verification");
return NULL;
+ }
loc = mono_image_rva_map (img, rva);
- if (!loc)
+ if (!loc) {
+ mono_error_set_bad_image (error, img, "Method has zero rva");
return NULL;
+ }
/*
* When parsing the types of local variables, we must pass any container available
container = mono_method_get_generic_container (method);
if (!container)
container = method->klass->generic_container;
- header = mono_metadata_parse_mh_full (img, container, (const char *)loc, &error);
- if (!header)
- mono_loader_set_error_from_mono_error (&error);
+ return mono_metadata_parse_mh_full (img, container, (const char *)loc, error);
+}
+MonoMethodHeader*
+mono_method_get_header (MonoMethod *method)
+{
+ MonoError error;
+ MonoMethodHeader *header = mono_method_get_header_checked (method, &error);
+ mono_error_cleanup (&error);
return header;
}
+
guint32
mono_method_get_flags (MonoMethod *method, guint32 *iflags)
{