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