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 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 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 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); }