[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void basic_init (AssemblyBuilder ab);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ static extern void UpdateNativeCustomAttributes (AssemblyBuilder ab);
+
/* Keep this in sync with codegen.cs in mcs */
private const AssemblyBuilderAccess COMPILER_ACCESS = (AssemblyBuilderAccess) 0x800;
cattrs = new CustomAttributeBuilder [1];
cattrs [0] = customBuilder;
}
+
+ /*
+ Only update the native list of custom attributes if we're adding one that is known to change dynamic execution behavior.
+ */
+ if (customBuilder.Ctor != null && customBuilder.Ctor.DeclaringType == typeof (System.Runtime.CompilerServices.RuntimeCompatibilityAttribute))
+ UpdateNativeCustomAttributes (this);
}
[ComVisible (true)]
invoke (444);
}
+ static Func<int> EmitDelegate (DynamicMethod dm) {
+ ILGenerator il = dm.GetILGenerator ();
+ var ret_val = il.DeclareLocal (typeof (int));
+ var leave_label = il.DefineLabel ();
+
+ //ret = 1;
+ il.Emit (OpCodes.Ldc_I4, 1);
+ il.Emit (OpCodes.Stloc, ret_val);
+
+ // try {
+ il.BeginExceptionBlock ();
+ // throw "hello";
+ il.Emit (OpCodes.Ldstr, "hello");
+ il.Emit (OpCodes.Throw, typeof (string));
+ // ret = 2
+ il.Emit (OpCodes.Ldc_I4, 2);
+ il.Emit (OpCodes.Stloc, ret_val);
+ // }
+ il.Emit (OpCodes.Leave, leave_label);
+ //catch (string)
+ il.BeginCatchBlock (typeof (string));
+ il.Emit (OpCodes.Pop);
+ // ret = 3
+ il.Emit (OpCodes.Ldc_I4, 3);
+ il.Emit (OpCodes.Stloc, ret_val);
+ //}
+ il.Emit (OpCodes.Leave, leave_label);
+ il.EndExceptionBlock ();
+
+ il.MarkLabel (leave_label);
+ //return ret;
+ il.Emit (OpCodes.Ldloc, ret_val);
+ il.Emit (OpCodes.Ret);
+
+ var dele = (Func<int>)dm.CreateDelegate (typeof (Func<int>));
+ return dele;
+ }
+
+ [Test] //see bxc #59334
+ public void ExceptionWrapping ()
+ {
+ AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly (new AssemblyName ("ehatevfheiw"), AssemblyBuilderAccess.Run);
+ AssemblyBuilder ab2 = AppDomain.CurrentDomain.DefineDynamicAssembly (new AssemblyName ("ddf4234"), AssemblyBuilderAccess.Run);
+ CustomAttributeBuilder cab = new CustomAttributeBuilder (
+ typeof (RuntimeCompatibilityAttribute).GetConstructor (new Type [0]),
+ new object [0],
+ new PropertyInfo[] { typeof (RuntimeCompatibilityAttribute).GetProperty ("WrapNonExceptionThrows") },
+ new object[] { true });
+ ab2.SetCustomAttribute (cab);
+
+ AssemblyBuilder ab3 = AppDomain.CurrentDomain.DefineDynamicAssembly (new AssemblyName ("frfhfher"), AssemblyBuilderAccess.Run);
+ //1 NamedArg. Property name: WrapNonExceptionThrows value: true (0x01)
+ byte[] blob = new byte[] { 0x01, 0x00, 0x01, 0x00, 0x54, 0x02, 0x16, 0x57, 0x72, 0x61, 0x70, 0x4E, 0x6F, 0x6E, 0x45, 0x78,
+ 0x63, 0x65, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x54, 0x68, 0x72, 0x6F, 0x77, 0x73, 0x01 };
+ ab3.SetCustomAttribute (typeof (RuntimeCompatibilityAttribute).GetConstructor (new Type [0]), blob);
+
+ DynamicMethod invoke_no_module = new DynamicMethod("throw_1", typeof (int), new Type [0]);
+ DynamicMethod invoke_with_module = new DynamicMethod("throw_2", typeof (int), new Type [0], typeof (DynamicMethodTest).Module);
+ DynamicMethod invoke_with_ab = new DynamicMethod("throw_3", typeof (int), new Type [0], ab.ManifestModule);
+ DynamicMethod invoke_with_ab2 = new DynamicMethod("throw_4", typeof (int), new Type [0], ab2.ManifestModule);
+ DynamicMethod invoke_with_ab3 = new DynamicMethod("throw_5", typeof (int), new Type [0], ab3.ManifestModule);
+
+ int result = 0;
+ try {
+ int res = EmitDelegate (invoke_no_module)();
+ Assert.AreEqual (3, res, "invoke_no_module bad return value");
+ } catch (RuntimeWrappedException e) {
+ Assert.Fail ("invoke_no_module threw RWE");
+ }
+
+ try {
+ int res = EmitDelegate (invoke_with_module)();
+ Assert.Fail ("invoke_with_module did not throw RWE");
+ } catch (RuntimeWrappedException e) {
+ }
+
+ try {
+ int res = EmitDelegate (invoke_with_ab)();
+ Assert.AreEqual (3, res, "invoke_with_ab bad return value");
+ } catch (RuntimeWrappedException e) {
+ Assert.Fail ("invoke_with_ab threw RWE");
+ }
+
+ try {
+ int res = EmitDelegate (invoke_with_ab2)();
+ Assert.Fail ("invoke_with_ab2 did not throw RWE");
+ } catch (RuntimeWrappedException e) {
+ }
+
+ try {
+ int res = EmitDelegate (invoke_with_ab3)();
+ Assert.Fail ("invoke_with_a3 did not throw RWE");
+ } catch (RuntimeWrappedException e) {
+ }
+ }
+
#if !MONODROID
// RUNTIME: crash
[Test]
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.
void *method_data;
};
+struct _MonoDynamicMethod {
+ MonoMethodWrapper method;
+ MonoAssembly *assembly;
+};
+
struct _MonoMethodPInvoke {
MonoMethod method;
gpointer addr;
ICALL_TYPE(CATTR_DATA, "System.Reflection.CustomAttributeData", CATTR_DATA_1)
ICALL(CATTR_DATA_1, "ResolveArgumentsInternal", ves_icall_System_Reflection_CustomAttributeData_ResolveArgumentsInternal)
-ICALL_TYPE(ASSEMB, "System.Reflection.Emit.AssemblyBuilder", ASSEMB_2)
+ICALL_TYPE(ASSEMB, "System.Reflection.Emit.AssemblyBuilder", ASSEMB_1)
+HANDLES(ICALL(ASSEMB_1, "UpdateNativeCustomAttributes", ves_icall_AssemblyBuilder_UpdateNativeCustomAttributes))
ICALL(ASSEMB_2, "basic_init", ves_icall_AssemblyBuilder_basic_init)
#ifndef DISABLE_REFLECTION_EMIT
void
ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb);
-MonoReflectionModule*
-ves_icall_AssemblyBuilder_InternalAddModule (MonoReflectionAssemblyBuilder *ab, MonoString *fileName);
+void
+ves_icall_AssemblyBuilder_UpdateNativeCustomAttributes (MonoReflectionAssemblyBuilderHandle assemblyb, MonoError *error);
MonoArray*
ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues);
mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
mono_loader_unlock ();
+}
+#else
+//FIXME some code compiled under DISABLE_REFLECTION_EMIT depends on this function, we should be more aggressively disabling things
+static void
+mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
+{
}
#endif
(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;
}
wrapperm->header = header;
+ MonoDynamicMethod *dm = (MonoDynamicMethod*)wrapperm;
+ dm->assembly = klass->image->assembly;
}
if (rmb->generic_params) {
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)) {
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);
mono_reflection_dynimage_basic_init (assemblyb);
}
+void
+ves_icall_AssemblyBuilder_UpdateNativeCustomAttributes (MonoReflectionAssemblyBuilderHandle assemblyb, MonoError *error)
+{
+ MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, assemblyb, cattrs);
+
+ MonoReflectionAssemblyHandle assembly_handle = MONO_HANDLE_CAST (MonoReflectionAssembly, assemblyb);
+ MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
+ g_assert (assembly);
+
+ mono_save_custom_attrs (assembly->image, assembly, MONO_HANDLE_RAW (cattrs));
+}
+
void
ves_icall_EnumBuilder_setup_enum_type (MonoReflectionTypeHandle enumtype,
MonoReflectionTypeHandle t,
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;