public object HandleFastCall(IAopProxy target, object executionTarget, int methodIndex, object[] rawParameters, Type returnType) { CallInfo info = MethodCache.GetCallInfo(methodIndex); MethodBase method = info.Method; IList interceptors = info.Interceptors; InterceptedParameter[] parameters = new InterceptedParameter[rawParameters.Length]; int index = 0; foreach (InvocationParameterInfo parameterInfo in info.InvocationParameterInfos) { InterceptedParameter parameter = new InterceptedParameter(parameterInfo, rawParameters, index); parameters[index] = parameter; index++; } #if NET2 MethodInvocation invocation = new MethodInvocation(target, executionTarget, method, method, parameters, rawParameters, returnType, interceptors); invocation.Handler = info.Handler; #else MethodInfo wrapperMethod = (MethodInfo)MethodCache.wrapperMethodLookup[info.MethodId]; MethodInvocation invocation = new MethodInvocation(target, executionTarget, method, wrapperMethod, parameters, rawParameters, returnType, interceptors); #endif return(invocation.Proceed()); }
private void BuildLookupTables(Type proxyType, IList aspects) { foreach (string methodId in wrapperMethods) { MethodInfo wrapperMethod = proxyType.GetMethod(methodId, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); MethodCache.wrapperMethodLookup[methodId] = wrapperMethod; MethodBase baseMethod = (MethodBase)MethodCache.methodLookup[methodId]; //array to return IList methodinterceptors = new ArrayList(); //fetch all aspects from the type-aspect lookup foreach (IGenericAspect aspect in aspects) { foreach (IPointcut pointcut in aspect.Pointcuts) { if (pointcut.IsMatch(baseMethod)) { foreach (object interceptor in pointcut.Interceptors) { methodinterceptors.Add(interceptor); } } } } MethodCache.methodInterceptorsLookup[methodId] = methodinterceptors; CallInfo callInfo = MethodCache.GetCallInfo(methodId); callInfo.Interceptors = methodinterceptors; } }
public object HandleFastCall(IAopProxy target, object executionTarget, int methodIndex, IList parameters, Type returnType) { CallInfo info = MethodCache.GetCallInfo(methodIndex); MethodBase method = info.Method; IList interceptors = info.Interceptors; #if NET2 MethodInvocation invocation = new MethodInvocation(target, executionTarget, method, method, parameters, returnType, interceptors); invocation.Handler = info.Handler; #else MethodInfo wrapperMethod = (MethodInfo)MethodCache.wrapperMethodLookup[info.MethodId]; MethodInvocation invocation = new MethodInvocation(target, executionTarget, method, wrapperMethod, parameters, returnType, interceptors); #endif return(invocation.Proceed()); }
private void BuildProxiedMixinMethod(TypeBuilder typeBuilder, MethodInfo method, FieldBuilder field) { if (method.DeclaringType == typeof(IAopProxy)) { BuildMixinWrapperMethod(method.Name, typeBuilder, method, field); return; } MethodInfo getTypeHandleMethod = typeof(Type).GetMethod("GetTypeFromHandle"); string wrapperName = GetMethodId(method.Name); wrapperMethods.Add(wrapperName); MethodCache.methodLookup[wrapperName] = method; // MethodCache.wrapperMethodLookup[wrapperName] = method; ParameterInfo[] parameterInfos = method.GetParameters(); Type[] parameterTypes = new Type[parameterInfos.Length]; for (int i = 0; i < parameterInfos.Length; i++) { parameterTypes[i] = parameterInfos[i].ParameterType; } string methodName = method.DeclaringType.FullName + "." + method.Name; MethodBuilder methodBuilder = typeBuilder.DefineMethod(methodName, MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Final | MethodAttributes.NewSlot | MethodAttributes.Virtual, CallingConventions.Standard, method.ReturnType, parameterTypes); typeBuilder.DefineMethodOverride(methodBuilder, method); methodBuilder.SetCustomAttribute(DebuggerStepThroughBuilder()); methodBuilder.SetCustomAttribute(DebuggerHiddenBuilder()); ILGenerator il = methodBuilder.GetILGenerator(); //----------------------------------- LocalBuilder paramList = il.DeclareLocal(typeof(object[])); //create param object[] il.Emit(OpCodes.Ldc_I4_S, parameterInfos.Length); il.Emit(OpCodes.Newarr, typeof(object)); il.Emit(OpCodes.Stloc, paramList); int j = 0; foreach (ParameterInfo parameter in parameterInfos) { //load arr il.Emit(OpCodes.Ldloc, paramList); //load index il.Emit(OpCodes.Ldc_I4, j); //load arg il.Emit(OpCodes.Ldarg, j + 1); //box if needed if (parameter.ParameterType.IsByRef) { il.Emit(OpCodes.Ldind_Ref); Type t = parameter.ParameterType.GetElementType(); if (t.IsValueType) { il.Emit(OpCodes.Box, t); } } else if (parameter.ParameterType.IsValueType) { il.Emit(OpCodes.Box, parameter.ParameterType); } il.Emit(OpCodes.Stelem_Ref); j++; } //----------------------------------- CallInfo callInfo = MethodCache.CreateCallInfo(method, parameterInfos, wrapperName); MethodInfo handleCallMethod = typeof(IAopProxy).GetMethod("HandleFastCall"); int methodNr = MethodCache.AddCallInfo(callInfo, wrapperName); //il.Emit(OpCodes.Ldc_I4 ,methodNr); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, field); // set the execution target to the mixin instance il.Emit(OpCodes.Ldc_I4, methodNr); il.Emit(OpCodes.Ldloc, paramList); il.Emit(OpCodes.Ldtoken, method.ReturnType); il.Emit(OpCodes.Call, getTypeHandleMethod); il.Emit(OpCodes.Callvirt, handleCallMethod); if (method.ReturnType == typeof(void)) { il.Emit(OpCodes.Pop); } else if (method.ReturnType.IsValueType) { il.Emit(OpCodes.Unbox, method.ReturnType); il.Emit(OpCodes.Ldobj, method.ReturnType); } MethodCache.CopyBackRefParams(il, parameterInfos, paramList); il.Emit(OpCodes.Ret); BuildMixinWrapperMethod(wrapperName, typeBuilder, method, field); }
private void BuildMethod(TypeBuilder typeBuilder, MethodInfo method) { MethodInfo getTypeHandleMethod = typeof(Type).GetMethod("GetTypeFromHandle"); string wrapperName = GetMethodId(method.Name); wrapperMethods.Add(wrapperName); MethodCache.methodLookup[wrapperName] = method; ParameterInfo[] parameterInfos = method.GetParameters(); Type[] parameterTypes = new Type[parameterInfos.Length]; for (int i = 0; i < parameterInfos.Length; i++) { parameterTypes[i] = parameterInfos[i].ParameterType; } string methodName = method.Name; MethodAttributes modifier = MethodAttributes.Public; if (method.IsFamily) { modifier = MethodAttributes.Family; } if (method.IsPublic) { modifier = MethodAttributes.Public; } if (method.IsFamilyOrAssembly) { modifier = MethodAttributes.FamORAssem; } if (method.IsFamilyAndAssembly) { modifier = MethodAttributes.FamANDAssem; } if (method.IsPrivate && methodName.IndexOf(".") >= 0) { int index = methodName.LastIndexOf(".") + 1; methodName = methodName.Substring(index); //modifier = MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Final | MethodAttributes.NewSlot; modifier = MethodAttributes.Public; } MethodBuilder methodBuilder = typeBuilder.DefineMethod(methodName, modifier | MethodAttributes.Virtual, CallingConventions.Standard, method.ReturnType, parameterTypes); methodBuilder.SetCustomAttribute(DebuggerStepThroughBuilder()); methodBuilder.SetCustomAttribute(DebuggerHiddenBuilder()); #if NET2 ReApplyAttributes(method); #endif for (int i = 0; i < parameterInfos.Length; i++) { } ILGenerator il = methodBuilder.GetILGenerator(); //----------------------------------- LocalBuilder paramList = il.DeclareLocal(typeof(object[])); //create param object[] il.Emit(OpCodes.Ldc_I4_S, parameterInfos.Length); il.Emit(OpCodes.Newarr, typeof(object)); il.Emit(OpCodes.Stloc, paramList); int j = 0; foreach (ParameterInfo parameter in parameterInfos) { //load arr il.Emit(OpCodes.Ldloc, paramList); //load index il.Emit(OpCodes.Ldc_I4, j); //load arg il.Emit(OpCodes.Ldarg, j + 1); //box if needed if (parameter.ParameterType.IsByRef) { il.Emit(OpCodes.Ldind_Ref); Type t = parameter.ParameterType.GetElementType(); if (t.IsValueType) { il.Emit(OpCodes.Box, t); } } else if (parameter.ParameterType.IsValueType) { il.Emit(OpCodes.Box, parameter.ParameterType); } il.Emit(OpCodes.Stelem_Ref); j++; } //----------------------------------- CallInfo callInfo = MethodCache.CreateCallInfo(method, parameterInfos, wrapperName); MethodInfo handleCallMethod = typeof(IAopProxy).GetMethod("HandleFastCall"); int methodNr = MethodCache.AddCallInfo(callInfo, wrapperName); //il.Emit(OpCodes.Ldc_I4 ,methodNr); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldc_I4, methodNr); il.Emit(OpCodes.Ldloc, paramList); il.Emit(OpCodes.Ldtoken, method.ReturnType); il.Emit(OpCodes.Call, getTypeHandleMethod); il.Emit(OpCodes.Callvirt, handleCallMethod); if (method.ReturnType == typeof(void)) { il.Emit(OpCodes.Pop); } else if (method.ReturnType.IsValueType) { il.Emit(OpCodes.Unbox, method.ReturnType); il.Emit(OpCodes.Ldobj, method.ReturnType); } MethodCache.CopyBackRefParams(il, parameterInfos, paramList); il.Emit(OpCodes.Ret); BuildWrapperMethod(wrapperName, typeBuilder, method); }
private void BuildLookupTables(Type proxyType, IList aspects, IList mixins) { MethodCache.methodsLookup[proxyType] = wrapperMethods; MethodCache.aspectsLookup[proxyType] = aspects; MethodCache.mixinsLookup[proxyType] = mixins; foreach (string methodId in wrapperMethods) { MethodInfo wrapperMethod = proxyType.GetMethod(methodId, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); MethodCache.wrapperMethodLookup[methodId] = wrapperMethod; MethodBase baseMethod = (MethodBase)MethodCache.methodLookup[methodId]; //array to return IList methodinterceptors = new ArrayList(); //fetch all aspects from the type-aspect lookup foreach (IAspect aspect in aspects) { IGenericAspect tmpAspect; if (aspect is IGenericAspect) { tmpAspect = (IGenericAspect)aspect; } else { tmpAspect = TypedToGenericConverter.Convert((ITypedAspect)aspect); } foreach (IPointcut pointcut in tmpAspect.Pointcuts) { if (pointcut.IsMatch(baseMethod, proxyType)) { foreach (object interceptor in pointcut.Interceptors) { methodinterceptors.Add(interceptor); } } } } foreach (FixedInterceptorAttribute fixedInterceptorAttribute in baseMethod.GetCustomAttributes(typeof(FixedInterceptorAttribute), true)) { foreach (Type type in fixedInterceptorAttribute.Types) { methodinterceptors.Add(engine.GetFixedInterceptor(type)); } } foreach (FixedInterceptorAttribute fixedInterceptorAttribute in baseMethod.DeclaringType.GetCustomAttributes(typeof(FixedInterceptorAttribute), true)) { foreach (Type type in fixedInterceptorAttribute.Types) { methodinterceptors.Add(engine.GetFixedInterceptor(type)); } } CheckRequiredMixins(baseMethod, methodinterceptors); MethodCache.methodInterceptorsLookup[methodId] = methodinterceptors; CallInfo callInfo = MethodCache.GetCallInfo(methodId); callInfo.Interceptors = methodinterceptors; } }
private void BuildConstructor(ConstructorInfo constructor, TypeBuilder typeBuilder, IList mixins, bool useCtorState) { string wrapperName = GetMethodId(constructor.Name); wrapperMethods.Add(wrapperName); MethodCache.methodLookup[wrapperName] = constructor; ParameterInfo[] parameterInfos = constructor.GetParameters(); //make proxy ctor param count same as superclass Type[] parameterTypes = null; if (useCtorState) { //use ctor state parameterTypes = new Type[parameterInfos.Length + 1]; //copy super ctor param types for (int i = 0; i <= parameterInfos.Length - 1; i++) { parameterTypes[i + 1] = parameterInfos[i].ParameterType; } parameterTypes[0] = typeof(object); } else { //no ctor state parameterTypes = new Type[parameterInfos.Length]; //copy super ctor param types for (int i = 0; i <= parameterInfos.Length - 1; i++) { parameterTypes[i] = parameterInfos[i].ParameterType; } } ConstructorBuilder proxyConstructor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, parameterTypes); ILGenerator il = proxyConstructor.GetILGenerator(); proxyConstructor.SetCustomAttribute(DebuggerStepThroughBuilder()); proxyConstructor.SetCustomAttribute(DebuggerHiddenBuilder()); #if NET2 ReApplyAttributes(constructor); #endif foreach (Type mixinType in mixins) { if (mixinType.IsInterface) { //ignore interface type mixins , they do not have an impelemntation } else { // il.EmitWriteLine("setting mixin instance " + mixinType.FullName) ; il.Emit(OpCodes.Ldarg_0); ConstructorInfo mixinCtor = (mixinType).GetConstructor(new Type[] {}); il.Emit(OpCodes.Newobj, mixinCtor); il.Emit(OpCodes.Stfld, GetMixinField(mixinType)); } } //associate iproxyaware mixins with this instance MethodInfo setProxyMethod = typeof(IProxyAware).GetMethod("SetProxy"); foreach (Type mixinType in mixins) { if (mixinType.IsInterface) { //ignore interface type mixins , they do not have an impelemntation } else { if (typeof(IProxyAware).IsAssignableFrom(mixinType)) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, GetMixinField(mixinType)); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, setProxyMethod); } } } //-------------------------- LocalBuilder paramList = il.DeclareLocal(typeof(object[])); //create param object[] il.Emit(OpCodes.Ldc_I4_S, parameterInfos.Length + 1); il.Emit(OpCodes.Newarr, typeof(object)); il.Emit(OpCodes.Stloc, paramList); //----------------------------------- int j = 0; foreach (Type parameterType in parameterTypes) { //load arr il.Emit(OpCodes.Ldloc, paramList); //load index il.Emit(OpCodes.Ldc_I4, j); //load arg il.Emit(OpCodes.Ldarg, j + 1); //box if needed if (parameterType.IsByRef) { il.Emit(OpCodes.Ldind_Ref); Type t = parameterType.GetElementType(); if (t.IsValueType) { il.Emit(OpCodes.Box, t); } } else if (parameterType.IsValueType) { il.Emit(OpCodes.Box, parameterType); } il.Emit(OpCodes.Stelem_Ref); j++; } //----------------------------------- CallInfo callInfo = MethodCache.CreateCallInfoForCtor(constructor, parameterInfos, wrapperName); MethodInfo handleCallMethod = typeof(IAopProxy).GetMethod("HandleFastCall"); int methodNr = MethodCache.AddCallInfo(callInfo, wrapperName); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldc_I4, methodNr); il.Emit(OpCodes.Ldloc, paramList); il.Emit(OpCodes.Ldtoken, typeof(void)); MethodInfo getTypeHandleMethod = typeof(Type).GetMethod("GetTypeFromHandle"); il.Emit(OpCodes.Call, getTypeHandleMethod); il.Emit(OpCodes.Callvirt, handleCallMethod); il.Emit(OpCodes.Pop); MethodCache.CopyBackRefParams(il, parameterInfos, paramList); il.Emit(OpCodes.Ret); //-------------- BuildWrapperMethod(wrapperName, typeBuilder, constructor); }
private void BuildConstructor(ConstructorInfo constructor, TypeBuilder typeBuilder, IList mixins) { string wrapperName = GetMethodId(constructor.Name); wrapperMethods.Add(wrapperName); MethodCache.methodLookup[wrapperName] = constructor; ParameterInfo[] parameters = constructor.GetParameters(); //make proxy ctor param count same as superclass Type[] parameterTypes = new Type[parameters.Length + 1]; //copy super ctor param types for (int i = 0; i <= parameters.Length - 1; i++) { parameterTypes[i + 1] = parameters[i].ParameterType; } parameterTypes[0] = typeof(object); ConstructorBuilder proxyConstructor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, parameterTypes); ILGenerator il = proxyConstructor.GetILGenerator(); proxyConstructor.SetCustomAttribute(DebuggerStepThroughBuilder()); proxyConstructor.SetCustomAttribute(DebuggerHiddenBuilder()); foreach (Type mixinType in mixins) { if (mixinType.IsInterface) { //ignore interface type mixins , they do not have an impelemntation } else { // il.EmitWriteLine("setting mixin instance " + mixinType.FullName) ; il.Emit(OpCodes.Ldarg_0); ConstructorInfo mixinCtor = (mixinType).GetConstructor(new Type[] {}); il.Emit(OpCodes.Newobj, mixinCtor); il.Emit(OpCodes.Stfld, GetMixinField(mixinType)); } } //associate iproxyaware mixins with this instance MethodInfo setProxyMethod = typeof(IProxyAware).GetMethod("SetProxy"); foreach (Type mixinType in mixins) { if (mixinType.IsInterface) { //ignore interface type mixins , they do not have an impelemntation } else { if (typeof(IProxyAware).IsAssignableFrom(mixinType)) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, GetMixinField(mixinType)); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, setProxyMethod); } } } //-------------------------- LocalBuilder paramList = il.DeclareLocal(typeof(ArrayList)); //create param arraylist ConstructorInfo arrayListCtor = typeof(ArrayList).GetConstructor(new Type[0]); il.Emit(OpCodes.Newobj, arrayListCtor); il.Emit(OpCodes.Stloc, paramList); ConstructorInfo interceptedParameterCtor = typeof(InterceptedParameter).GetConstructors()[0]; MethodInfo arrayListAddMethod = typeof(ArrayList).GetMethod("Add"); MethodInfo getTypeMethod = typeof(Type).GetMethod("GetType", new Type[1] { typeof(string) }); il.Emit(OpCodes.Ldloc, paramList); il.Emit(OpCodes.Ldstr, "_state"); il.Emit(OpCodes.Ldc_I4, 0); il.Emit(OpCodes.Ldstr, typeof(object).FullName); il.Emit(OpCodes.Call, getTypeMethod); il.Emit(OpCodes.Ldarg, 0 + 1); il.Emit(OpCodes.Ldc_I4, (int)ParameterType.ByVal); il.Emit(OpCodes.Newobj, interceptedParameterCtor); il.Emit(OpCodes.Callvirt, arrayListAddMethod); il.Emit(OpCodes.Pop); int j = 1; foreach (ParameterInfo parameter in parameters) { il.Emit(OpCodes.Ldloc, paramList); string paramName = parameter.Name; if (paramName == null) { paramName = "param" + j.ToString(); } il.Emit(OpCodes.Ldstr, paramName); il.Emit(OpCodes.Ldc_I4, j); il.Emit(OpCodes.Ldstr, parameter.ParameterType.FullName.Replace("&", "")); il.Emit(OpCodes.Call, getTypeMethod); il.Emit(OpCodes.Ldarg, j + 1); if (parameter.ParameterType.FullName.IndexOf("&") >= 0) { il.Emit(OpCodes.Ldind_Ref); Type t = Type.GetType(parameter.ParameterType.FullName.Replace("&", "")); if (t.IsValueType) { il.Emit(OpCodes.Box, t); } } if (parameter.ParameterType.IsValueType) { il.Emit(OpCodes.Box, parameter.ParameterType); } il.Emit(OpCodes.Ldc_I4, (int)ParameterType.ByVal); il.Emit(OpCodes.Newobj, interceptedParameterCtor); il.Emit(OpCodes.Callvirt, arrayListAddMethod); il.Emit(OpCodes.Pop); j++; } #if NET2 CallInfo callInfo = new CallInfo(wrapperName, constructor, new ArrayList(), FastCall.GetMethodInvoker(constructor)); #else CallInfo callInfo = new CallInfo(wrapperName, constructor, new ArrayList()); #endif MethodInfo handleCallMethod = typeof(IAopProxy).GetMethod("HandleFastCall"); int methodNr = MethodCache.AddCallInfo(callInfo, wrapperName); //il.Emit(OpCodes.Ldc_I4 ,methodNr); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldc_I4, methodNr); il.Emit(OpCodes.Ldloc, paramList); il.Emit(OpCodes.Ldstr, typeof(void).FullName); il.Emit(OpCodes.Call, getTypeMethod); il.Emit(OpCodes.Callvirt, handleCallMethod); il.Emit(OpCodes.Pop); j = 1; MethodInfo get_ItemMethod = typeof(ArrayList).GetMethod("get_Item", new Type[1] { typeof(int) }); foreach (ParameterInfo parameter in parameters) { if (parameter.ParameterType.FullName.IndexOf("&") >= 0) { il.Emit(OpCodes.Ldarg, j + 1); il.Emit(OpCodes.Ldloc, paramList); il.Emit(OpCodes.Ldc_I4, j); il.Emit(OpCodes.Callvirt, get_ItemMethod); il.Emit(OpCodes.Castclass, typeof(InterceptedParameter)); FieldInfo valueField = typeof(InterceptedParameter).GetField("Value"); il.Emit(OpCodes.Ldfld, valueField); Type t = Type.GetType(parameter.ParameterType.FullName.Replace("&", "")); if (t.IsValueType) { il.Emit(OpCodes.Unbox, t); il.Emit(OpCodes.Ldobj, t); il.Emit(OpCodes.Stobj, t); } else { il.Emit(OpCodes.Castclass, t); il.Emit(OpCodes.Stind_Ref); } } j++; } il.Emit(OpCodes.Ret); //-------------- BuildWrapperMethod(wrapperName, typeBuilder, constructor); }
private void BuildMixinMethod(TypeBuilder typeBuilder, MethodInfo method, FieldBuilder field) { if (method.DeclaringType == typeof(IAopProxy)) { BuildMixinWrapperMethod(method.Name, typeBuilder, method, field); return; } string wrapperName = GetMethodId(method.Name); wrapperMethods.Add(wrapperName); MethodCache.methodLookup[wrapperName] = method; // MethodCache.wrapperMethodLookup[wrapperName] = method; ParameterInfo[] parameterInfos = method.GetParameters(); Type[] parameterTypes = new Type[parameterInfos.Length]; for (int i = 0; i < parameterInfos.Length; i++) { parameterTypes[i] = parameterInfos[i].ParameterType; } MethodBuilder methodBuilder = typeBuilder.DefineMethod(method.Name, MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard, method.ReturnType, parameterTypes); methodBuilder.SetCustomAttribute(DebuggerStepThroughBuilder()); methodBuilder.SetCustomAttribute(DebuggerHiddenBuilder()); for (int i = 0; i < parameterInfos.Length; i++) { } ILGenerator il = methodBuilder.GetILGenerator(); LocalBuilder paramList = il.DeclareLocal(typeof(ArrayList)); //create param arraylist ConstructorInfo arrayListCtor = typeof(ArrayList).GetConstructor(new Type[0]); il.Emit(OpCodes.Newobj, arrayListCtor); il.Emit(OpCodes.Stloc, paramList); int j = 0; ConstructorInfo interceptedParameterCtor = typeof(InterceptedParameter).GetConstructors()[0]; MethodInfo arrayListAddMethod = typeof(ArrayList).GetMethod("Add"); MethodInfo getTypeMethod = typeof(Type).GetMethod("GetType", new Type[1] { typeof(string) }); foreach (ParameterInfo parameter in parameterInfos) { il.Emit(OpCodes.Ldloc, paramList); string paramName = parameter.Name; if (paramName == null) { paramName = "param" + j.ToString(); } il.Emit(OpCodes.Ldstr, paramName); il.Emit(OpCodes.Ldc_I4, j); il.Emit(OpCodes.Ldstr, parameter.ParameterType.FullName.Replace("&", "")); il.Emit(OpCodes.Call, getTypeMethod); il.Emit(OpCodes.Ldarg, j + 1); if (parameter.ParameterType.FullName.IndexOf("&") >= 0) { il.Emit(OpCodes.Ldind_Ref); Type t = Type.GetType(parameter.ParameterType.FullName.Replace("&", "")); if (t.IsValueType) { il.Emit(OpCodes.Box, t); } } if (parameter.ParameterType.IsValueType) { il.Emit(OpCodes.Box, parameter.ParameterType); } il.Emit(OpCodes.Ldc_I4, (int)ParameterType.ByVal); il.Emit(OpCodes.Newobj, interceptedParameterCtor); il.Emit(OpCodes.Callvirt, arrayListAddMethod); il.Emit(OpCodes.Pop); j++; } #if NET2 CallInfo callInfo = new CallInfo(wrapperName, method, new ArrayList(), FastCall.GetMethodInvoker(method)); #else CallInfo callInfo = new CallInfo(wrapperName, method, new ArrayList()); #endif MethodInfo handleCallMethod = typeof(IAopProxy).GetMethod("HandleFastCall"); int methodNr = MethodCache.AddCallInfo(callInfo, wrapperName); //il.Emit(OpCodes.Ldc_I4 ,methodNr); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, field); // set the execution target to the mixin instance il.Emit(OpCodes.Ldc_I4, methodNr); il.Emit(OpCodes.Ldloc, paramList); il.Emit(OpCodes.Ldstr, method.ReturnType.FullName); il.Emit(OpCodes.Call, getTypeMethod); il.Emit(OpCodes.Callvirt, handleCallMethod); if (method.ReturnType == typeof(void)) { il.Emit(OpCodes.Pop); } else if (method.ReturnType.IsValueType) { il.Emit(OpCodes.Unbox, method.ReturnType); il.Emit(OpCodes.Ldobj, method.ReturnType); } j = 0; MethodInfo get_ItemMethod = typeof(ArrayList).GetMethod("get_Item", new Type[1] { typeof(int) }); foreach (ParameterInfo parameter in parameterInfos) { if (parameter.ParameterType.FullName.IndexOf("&") >= 0) { il.Emit(OpCodes.Ldarg, j + 1); il.Emit(OpCodes.Ldloc, paramList); il.Emit(OpCodes.Ldc_I4, j); il.Emit(OpCodes.Callvirt, get_ItemMethod); il.Emit(OpCodes.Castclass, typeof(InterceptedParameter)); FieldInfo valueField = typeof(InterceptedParameter).GetField("Value"); il.Emit(OpCodes.Ldfld, valueField); Type t = Type.GetType(parameter.ParameterType.FullName.Replace("&", "")); if (t.IsValueType) { il.Emit(OpCodes.Unbox, t); il.Emit(OpCodes.Ldobj, t); il.Emit(OpCodes.Stobj, t); } else { il.Emit(OpCodes.Castclass, t); il.Emit(OpCodes.Stind_Ref); } } j++; } il.Emit(OpCodes.Ret); BuildMixinWrapperMethod(wrapperName, typeBuilder, method, field); }
private void BuildMethod(string methodName, TypeBuilder typeBuilder, MethodInfo method) { string wrapperName = GetMethodId(method.Name); wrapperMethods.Add(wrapperName); MethodCache.methodLookup[wrapperName] = method; ParameterInfo[] parameterInfos = method.GetParameters(); Type[] parameterTypes = new Type[parameterInfos.Length]; for (int i = 0; i < parameterInfos.Length; i++) { parameterTypes[i] = parameterInfos[i].ParameterType; } MethodBuilder methodBuilder = typeBuilder.DefineMethod(methodName, MethodAttributes.NewSlot | MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig, CallingConventions.Standard, method.ReturnType, parameterTypes); for (int i = 0; i < parameterInfos.Length; i++) { } typeBuilder.DefineMethodOverride(methodBuilder, method); ILGenerator il = methodBuilder.GetILGenerator(); //-------------------------- LocalBuilder paramList = il.DeclareLocal(typeof(object[])); //create param object[] il.Emit(OpCodes.Ldc_I4_S, parameterInfos.Length + 1); il.Emit(OpCodes.Newarr, typeof(object)); il.Emit(OpCodes.Stloc, paramList); //----------------------------------- int j = 0; foreach (Type parameterType in parameterTypes) { //load arr il.Emit(OpCodes.Ldloc, paramList); //load index il.Emit(OpCodes.Ldc_I4, j); //load arg il.Emit(OpCodes.Ldarg, j + 1); //box if needed if (parameterType.IsByRef) { il.Emit(OpCodes.Ldind_Ref); Type t = parameterType.GetElementType(); if (t.IsValueType) { il.Emit(OpCodes.Box, t); } } else if (parameterType.IsValueType) { il.Emit(OpCodes.Box, parameterType); } il.Emit(OpCodes.Stelem_Ref); j++; } //----------------------------------- CallInfo callInfo = MethodCache.CreateCallInfo(method, parameterInfos, wrapperName); MethodInfo handleCallMethod = typeof(IAopProxy).GetMethod("HandleFastCall"); int methodNr = MethodCache.AddCallInfo(callInfo, wrapperName); //il.Emit(OpCodes.Ldc_I4 ,methodNr); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, that); // load the execution target il.Emit(OpCodes.Ldc_I4, methodNr); il.Emit(OpCodes.Ldloc, paramList); il.Emit(OpCodes.Ldstr, method.ReturnType.FullName); MethodInfo getTypeMethod = typeof(Type).GetMethod("GetType", new Type[1] { typeof(string) }); il.Emit(OpCodes.Call, getTypeMethod); il.Emit(OpCodes.Callvirt, handleCallMethod); if (method.ReturnType == typeof(void)) { il.Emit(OpCodes.Pop); } else if (method.ReturnType.IsValueType) { il.Emit(OpCodes.Unbox, method.ReturnType); il.Emit(OpCodes.Ldobj, method.ReturnType); } MethodCache.CopyBackRefParams(il, parameterInfos, paramList); il.Emit(OpCodes.Ret); BuildWrapperMethod(wrapperName, typeBuilder, method); }