internal static CallInfo CreateCallInfo(MethodInfo method, ParameterInfo[] parameterInfos, string wrapperName) { InvocationParameterInfo[] parameters = new InvocationParameterInfo[parameterInfos.Length]; for (int i = 0; i < parameterInfos.Length; i++) { ParameterInfo paramInfo = parameterInfos[i]; Type paramType = paramInfo.ParameterType; if (paramType.IsByRef) { paramType = paramType.GetElementType(); } InvocationParameterInfo invocationParamInfo = new InvocationParameterInfo(paramInfo.Name, i, paramType, ParameterType.ByVal); parameters[i] = invocationParamInfo; } #if NET2 return(new CallInfo(wrapperName, method, new ArrayList(), parameters, FastCall.GetMethodInvoker(method))); #else return(new CallInfo(wrapperName, method, new ArrayList(), parameters)); #endif }
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); }