1 //------------------------------------------------------------------------------
2 // <copyright file="ArglessEventHandlerProxy.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //------------------------------------------------------------------------------
7 namespace System.Web.Util {
9 using System.Reflection;
10 using System.Reflection.Emit;
11 using System.Security.Permissions;
12 using System.Security;
15 * Proxy that provides EventHandler and redirects it to arg-less method on the given object
17 internal class ArglessEventHandlerProxy {
18 private Object _target;
19 private MethodInfo _arglessMethod;
21 internal ArglessEventHandlerProxy(Object target, MethodInfo arglessMethod) {
22 Debug.Assert(arglessMethod.GetParameters().Length == 0);
25 _arglessMethod = arglessMethod;
28 [ReflectionPermission(SecurityAction.Assert, Flags=ReflectionPermissionFlag.RestrictedMemberAccess)]
29 internal void Callback(Object sender, EventArgs e) {
30 _arglessMethod.Invoke(_target, new Object[0]);
33 internal EventHandler Handler {
35 return new EventHandler(Callback);
40 internal delegate void VoidMethod();
42 internal class CalliEventHandlerDelegateProxy {
43 private delegate void ParameterlessDelegate();
44 private delegate void ParameterfulDelegate(object sender, EventArgs e);
46 private IntPtr _functionPointer;
47 private Object _target;
48 private bool _argless;
50 internal CalliEventHandlerDelegateProxy(Object target, IntPtr functionPointer, bool argless) {
53 _functionPointer = functionPointer;
56 internal void Callback(Object sender, EventArgs e) {
58 ParameterlessDelegate del = FastDelegateCreator<ParameterlessDelegate>.BindTo(_target, _functionPointer);
62 ParameterfulDelegate del = FastDelegateCreator<ParameterfulDelegate>.BindTo(_target, _functionPointer);
67 internal EventHandler Handler {
69 return new EventHandler(Callback);
74 #if LCG_Implementation
75 internal delegate void ArglessMethod(IntPtr methodPtr, Object target);
76 internal delegate void EventArgMethod(IntPtr methodPtr, Object target, Object source, EventArgs e);
78 internal class CalliHelper {
79 internal static ArglessMethod ArglessFunctionCaller;
80 internal static EventArgMethod EventArgFunctionCaller;
82 // Make sure we have reflection permission to use ReflectionEmit and access method
83 [ReflectionPermission(SecurityAction.Assert, Flags = ReflectionPermissionFlag.ReflectionEmit | ReflectionPermissionFlag.MemberAccess)]
84 static CalliHelper() {
85 // generate void(void) calli
86 DynamicMethod dm = new DynamicMethod("void_calli",
88 new Type[] { typeof(IntPtr) /* function ptr */, typeof(Object) /* target */},
89 typeof(CalliHelper).Module);
90 ILGenerator ilg = dm.GetILGenerator();
92 ilg.Emit(OpCodes.Ldarg_1);
93 ilg.Emit(OpCodes.Ldarg_0);
94 ilg.EmitCalli(OpCodes.Calli, CallingConventions.HasThis, typeof(void), new Type[0], null);
95 ilg.Emit(OpCodes.Ret);
96 ArglessFunctionCaller = (ArglessMethod)dm.CreateDelegate(typeof(ArglessMethod));
98 // generate void(Object, EventArgs) calli
99 dm = new DynamicMethod("eventarg_calli",
101 new Type[] { typeof(IntPtr) /* function ptr */, typeof(Object) /* target */, typeof(Object) /* sender */, typeof(EventArgs) },
102 typeof(CalliHelper).Module);
103 ilg = dm.GetILGenerator();
105 ilg.Emit(OpCodes.Ldarg_1);
106 ilg.Emit(OpCodes.Ldarg_2);
107 ilg.Emit(OpCodes.Ldarg_3);
108 ilg.Emit(OpCodes.Ldarg_0);
109 ilg.EmitCalli(OpCodes.Calli, CallingConventions.HasThis, typeof(void), new Type[] { typeof(object) /* sender */, typeof(EventArgs) }, null);
110 ilg.Emit(OpCodes.Ret);
111 EventArgFunctionCaller = (EventArgMethod)dm.CreateDelegate(typeof(EventArgMethod));
114 #endif //LCG_Implementation
116 #if Reflection_Emit_Implementation
117 internal delegate void ArglessMethod(IntPtr methodPtr, Object target);
118 internal delegate void EventArgMethod(IntPtr methodPtr, Object target, Object source, EventArgs e);
120 internal class CalliHelper {
122 internal static ArglessMethod ArglessFunctionCaller;
123 internal static EventArgMethod EventArgFunctionCaller;
125 // Make sure we have reflection permission to use ReflectionEmit and access method
126 [ReflectionPermission(SecurityAction.Assert, Flags = ReflectionPermissionFlag.ReflectionEmit | ReflectionPermissionFlag.MemberAccess)]
127 static CalliHelper() {
129 AssemblyName an = new AssemblyName("CalliHelper");
130 AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
131 ModuleBuilder mb = ab.DefineDynamicModule("CalliHelper.dll");
133 ConstructorInfo ci = typeof(CLSCompliantAttribute).GetConstructor(new Type[] { typeof(bool) });
134 CustomAttributeBuilder cb = new CustomAttributeBuilder(ci, new object[] { true });
135 mb.SetCustomAttribute(cb);
137 TypeBuilder tb = mb.DefineType("System.Web.Util.CalliHelper", TypeAttributes.NotPublic | TypeAttributes.Sealed);
138 MethodBuilder methb = tb.DefineMethod("EventArgMethod", MethodAttributes.Assembly | MethodAttributes.Static, typeof(void), new Type[] { typeof(IntPtr), typeof(object), typeof(object), typeof(EventArgs) });
139 ILGenerator ilg = methb.GetILGenerator();
141 ilg.Emit(OpCodes.Ldarg_1);
142 ilg.Emit(OpCodes.Ldarg_2);
143 ilg.Emit(OpCodes.Ldarg_3);
144 ilg.Emit(OpCodes.Ldarg_0);
145 ilg.EmitCalli(OpCodes.Calli, CallingConventions.HasThis, typeof(void), new Type[] { typeof(object), typeof(EventArgs) }, null);
146 ilg.Emit(OpCodes.Ret);
148 methb = tb.DefineMethod("ArglessMethod", MethodAttributes.Assembly | MethodAttributes.Static, typeof(void), new Type[] { typeof (IntPtr), typeof(object) });
149 ilg = methb.GetILGenerator();
151 ilg.Emit(OpCodes.Ldarg_1);
152 ilg.Emit(OpCodes.Ldarg_0);
153 ilg.EmitCalli(OpCodes.Calli, CallingConventions.HasThis, typeof(void), new Type[0], null);
154 ilg.Emit(OpCodes.Ret);
156 Type t = tb.CreateType();
157 ArglessFunctionCaller = (ArglessMethod)Delegate.CreateDelegate(typeof(ArglessMethod), t, "ArglessMethod", true);
158 EventArgFunctionCaller = (EventArgMethod)Delegate.CreateDelegate(typeof(EventArgMethod), t, "EventArgMethod", true);
160 //ab.Save("CalliHelper.dll");
163 #endif // Reflection_Emit_Implementation