From 446728b335f0492671fc21ce76b27d063dcb7653 Mon Sep 17 00:00:00 2001 From: Rodrigo Kumpera Date: Wed, 13 Sep 2017 16:12:57 -0700 Subject: [PATCH] [runtime] Handle RuntimeWrappedException and dynamic methods. Introduce MonoDynamicMethod that holds the assembly of a DM (and TB). Use it to determine the RuntimeWrappedException policy for exceptions. This is needed cuz the assembly of a MonoMethod is normally found using method->parent->image->assembly. But this doesn't work with DynamicMethods that don't define an owner type as they are forced to corlib's policy. The default policy for DM's is to not wrap those exceptions and in the case a Module is provided, the policy of that module must be respected. This commit handles all cases but when a Module is a SRE module. --- mono/metadata/class-internals.h | 6 ++++++ mono/metadata/sre.c | 8 +++++++- mono/mini/mini-exceptions.c | 5 +++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/mono/metadata/class-internals.h b/mono/metadata/class-internals.h index f744fc1fdc4..e3d9e187417 100644 --- a/mono/metadata/class-internals.h +++ b/mono/metadata/class-internals.h @@ -27,6 +27,7 @@ extern gboolean mono_align_small_structs; typedef struct _MonoMethodWrapper MonoMethodWrapper; typedef struct _MonoMethodInflated MonoMethodInflated; typedef struct _MonoMethodPInvoke MonoMethodPInvoke; +typedef struct _MonoDynamicMethod MonoDynamicMethod; /* Properties that applies to a group of structs should better use a higher number * to avoid colision with type specific properties. @@ -100,6 +101,11 @@ struct _MonoMethodWrapper { void *method_data; }; +struct _MonoDynamicMethod { + MonoMethodWrapper method; + MonoAssembly *assembly; +}; + struct _MonoMethodPInvoke { MonoMethod method; gpointer addr; diff --git a/mono/metadata/sre.c b/mono/metadata/sre.c index 649791e7bea..c2c3ac2d171 100644 --- a/mono/metadata/sre.c +++ b/mono/metadata/sre.c @@ -2777,7 +2777,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)) m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1); else - m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1); + m = (MonoMethod *)image_g_new0 (image, MonoDynamicMethod, 1); wrapperm = (MonoMethodWrapper*)m; @@ -2872,6 +2872,8 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, } wrapperm->header = header; + MonoDynamicMethod *dm = (MonoDynamicMethod*)wrapperm; + dm->assembly = klass->image->assembly; } if (rmb->generic_params) { @@ -3908,6 +3910,7 @@ reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb, Mono rmb.refs [i + 1] = handle_class; } + MonoAssembly *ass = NULL; if (mb->owner) { MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error); if (!is_ok (error)) { @@ -3915,11 +3918,14 @@ reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb, Mono return FALSE; } klass = mono_class_from_mono_type (owner_type); + ass = klass->image->assembly; } else { klass = mono_defaults.object_class; + ass = (mb->module && mb->module->image) ? mb->module->image->assembly : NULL; } mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error); + ((MonoDynamicMethod*)handle)->assembly = ass; g_free (rmb.refs); return_val_if_nok (error, FALSE); diff --git a/mono/mini/mini-exceptions.c b/mono/mini/mini-exceptions.c index 10cf1b75cb1..e3461a80aec 100644 --- a/mono/mini/mini-exceptions.c +++ b/mono/mini/mini-exceptions.c @@ -1415,6 +1415,11 @@ wrap_non_exception_throws (MonoMethod *m) int i; gboolean val = FALSE; + if (m->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD) { + MonoDynamicMethod *dm = (MonoDynamicMethod *)m; + if (dm->assembly) + ass = dm->assembly; + } g_assert (ass); if (ass->wrap_non_exception_throws_inited) return ass->wrap_non_exception_throws; -- 2.25.1