Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kliger <aleksey@xamarin.com>2017-09-27 21:01:47 +0300
committerMarek Safar <marek.safar@gmail.com>2017-10-06 12:12:06 +0300
commitfbc487ff424c479c25d0bbd24110d34890ffd793 (patch)
treef6698a607aa5ca1e63fdbc2652ddf464fa8fdfea
parent72c4a0ca0847c2c16e984866b05050e56595e421 (diff)
[sre] register a canonical MonoReflectionMethod for a methodref tokenmono-5.4.0.212
In mono_image_create_token we are passed in a managed reflection object and we need to create a token for it and optionally register it so that we can resolve that token back to a runtime structure and managed object later. For a MonoReflectionMethod object that refers to a method from outside the current dynamic image, we need to generate a memberref token. It will be the same token for the same underlying MonoMethod*. When we go to register the token with mono_dynamic_image_register_token we need to pass a managed object. Unfortunately two MonoReflectionMethod objects could refer to the same MonoMethod* but differ in their ReflectedType, so just registering the passed-in MonoReflectionMethod means we could assert in mono_dynamic_image_register_token because previously we may have registered the same method via a different ReflectedType. So what we do is we cal mono_method_get_object_handle with NULL for the reflected type - which corresponds to just using the DeclaringType of the given MonoMethod*. Fixes https://bugzilla.xamarin.com/show_bug.cgi?id=59364
-rw-r--r--mono/metadata/sre.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/mono/metadata/sre.c b/mono/metadata/sre.c
index eb06bcf72cf..a009f41ecd8 100644
--- a/mono/metadata/sre.c
+++ b/mono/metadata/sre.c
@@ -1174,7 +1174,21 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
how_collide = MONO_DYN_IMAGE_TOK_NEW;
}
} else {
- token = mono_image_get_methodref_token (assembly, method, create_open_instance);
+ guint32 methodref_token = mono_image_get_methodref_token (assembly, method, create_open_instance);
+ /* We need to register a 'canonical' object. The same
+ * MonoMethod could have been reflected via different
+ * classes so the MonoReflectionMethod:reftype could be
+ * different, and the object lookup in
+ * dynamic_image_register_token would assert assert. So
+ * we pick the MonoReflectionMethod object that has the
+ * reflected type as NULL (ie, take the declaring type
+ * of the method) */
+ MonoReflectionMethodHandle canonical_obj =
+ mono_method_get_object_handle (MONO_HANDLE_DOMAIN (obj), method, NULL, error);
+ if (!is_ok (error))
+ goto leave;
+ MONO_HANDLE_ASSIGN (register_obj, canonical_obj);
+ token = methodref_token;
}
/*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
} else if (strcmp (klass->name, "MonoField") == 0) {
@@ -1186,7 +1200,15 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
token = MONO_TOKEN_FIELD_DEF | field_table_idx;
how_collide = MONO_DYN_IMAGE_TOK_NEW;
} else {
- token = mono_image_get_fieldref_token (assembly, field);
+ guint32 fieldref_token = mono_image_get_fieldref_token (assembly, field);
+ /* Same as methodref: get a canonical object to
+ * register with the token. */
+ MonoReflectionFieldHandle canonical_obj =
+ mono_field_get_object_handle (MONO_HANDLE_DOMAIN (obj), field->parent, field, error);
+ if (!is_ok (error))
+ goto leave;
+ MONO_HANDLE_ASSIGN (register_obj, canonical_obj);
+ token = fieldref_token;
}
/*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
} else if (strcmp (klass->name, "MonoArrayMethod") == 0) {