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