[runtime] Handle RuntimeWrappedException and dynamic methods.
authorRodrigo Kumpera <kumpera@gmail.com>
Wed, 13 Sep 2017 23:12:57 +0000 (16:12 -0700)
committerRodrigo Kumpera <kumpera@gmail.com>
Mon, 25 Sep 2017 20:23:16 +0000 (13:23 -0700)
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
mono/metadata/sre.c
mono/mini/mini-exceptions.c

index f744fc1fdc4c66144ab648e52b7f9f0160953c40..e3d9e18741752ec88e7136cda18776ea7d25c736 100644 (file)
@@ -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;
index 649791e7beafcb4104a181e0c720a2509ea53d4b..c2c3ac2d1718f58ba23a325f5e58d3d7eab69978 100644 (file)
@@ -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);
 
index 10cf1b75cb194d9051761962546b5ffba8b9f8f8..e3461a80aec1631eb756b7d15f18d5133125ede3 100644 (file)
@@ -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;