public DefineMethodOverride ( System methodInfoBody, System methodInfoDeclaration ) : void | ||
methodInfoBody | System | |
methodInfoDeclaration | System | |
Résultat | void |
public void ImplementProxy(TypeBuilder typeBuilder) { // Implement the IProxy interface typeBuilder.AddInterfaceImplementation(typeof (IProxy)); field = typeBuilder.DefineField("__interceptor", typeof (IInterceptor), FieldAttributes.Private); // Implement the getter MethodBuilder getterMethod = typeBuilder.DefineMethod("get_Interceptor", InterceptorMethodsAttributes, CallingConventions.HasThis, typeof(IInterceptor), new System.Type[0]); getterMethod.SetImplementationFlags(MethodImplAttributes.Managed | MethodImplAttributes.IL); ILGenerator IL = getterMethod.GetILGenerator(); // This is equivalent to: // get { return __interceptor; IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, field); IL.Emit(OpCodes.Ret); // Implement the setter MethodBuilder setterMethod = typeBuilder.DefineMethod("set_Interceptor", InterceptorMethodsAttributes, CallingConventions.HasThis, typeof (void), new[] {typeof (IInterceptor)}); setterMethod.SetImplementationFlags(MethodImplAttributes.Managed | MethodImplAttributes.IL); IL = setterMethod.GetILGenerator(); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldarg_1); IL.Emit(OpCodes.Stfld, field); IL.Emit(OpCodes.Ret); MethodInfo originalSetter = typeof (IProxy).GetMethod("set_Interceptor"); MethodInfo originalGetter = typeof (IProxy).GetMethod("get_Interceptor"); typeBuilder.DefineMethodOverride(setterMethod, originalSetter); typeBuilder.DefineMethodOverride(getterMethod, originalGetter); }
public void ImplementProxy(TypeBuilder typeBuilder) { typeBuilder.AddInterfaceImplementation(typeof (IProxy)); InterceptorField = typeBuilder .DefineField("__interceptor", typeof (Proxy.DynamicProxy.IInterceptor), FieldAttributes.Private); var getterMethod = typeBuilder .DefineMethod("get_Interceptor", InterceptorMethodsAttributes, CallingConventions.HasThis, typeof (Proxy.DynamicProxy.IInterceptor), new System.Type[0]); getterMethod.SetImplementationFlags(MethodImplAttributes.IL); var il = getterMethod.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, InterceptorField); il.Emit(OpCodes.Ret); var setterMethod = typeBuilder .DefineMethod("set_Interceptor", InterceptorMethodsAttributes, CallingConventions.HasThis, typeof (void), new[] {typeof (Proxy.DynamicProxy.IInterceptor)}); setterMethod.SetImplementationFlags(MethodImplAttributes.IL); il = setterMethod.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Stfld, InterceptorField); il.Emit(OpCodes.Ret); var originalSetter = typeof (IProxy).GetMethod("set_Interceptor"); var originalGetter = typeof (IProxy).GetMethod("get_Interceptor"); typeBuilder.DefineMethodOverride(setterMethod, originalSetter); typeBuilder.DefineMethodOverride(getterMethod, originalGetter); }
/// <summary> /// Create property with explicit implementation of getter and setter, with no method defined. /// </summary> private PropertyDefinition AddProperty(TypeDefinition declaringType, string name, TypeReference propertyType, string explicitPrefix, PropertyInfo overridedProp) { var proxyPropDef = declaringType.DefineProperty(explicitPrefix + name, PropertyAttributes.None | PropertyAttributes.SpecialName, propertyType, null); const MethodAttributes methodAttributes = MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName; var overridedGetMethod = overridedProp.GetGetMethod(); if (overridedGetMethod != null) { var proxyPropGetter = declaringType.DefineMethod( $"{explicitPrefix}get_{name}", methodAttributes, propertyType, Type.EmptyTypes); declaringType.DefineMethodOverride(proxyPropGetter, overridedGetMethod); proxyPropDef.SetGetMethod(proxyPropGetter); } var overridedSetMethod = overridedProp.GetSetMethod(); if (overridedSetMethod != null) { var proxyPropSetter = declaringType.DefineMethod( $"{explicitPrefix}set_{name}", methodAttributes, null, new[] { propertyType }); proxyPropSetter.DefineParameter(0, ParameterAttributes.None, "value"); declaringType.DefineMethodOverride(proxyPropSetter, overridedSetMethod); proxyPropDef.SetSetMethod(proxyPropSetter); } return(proxyPropDef); }
/// <summary> /// Creates a <see cref="MethodBuilder"/> and implements a default wrapper. /// </summary> /// <param name="owner">The type that will own this method.</param> /// <param name="interfaceType">Type of interface implemented by the <paramref name="owner"/>.</param> /// <param name="overrideMethod">Method to override.</param> /// <param name="fieldBuilders">Fields specified by the <see paramref="owner"/>.</param> /// <returns>MethodBuilder with an already implemented wrapper.</returns> public MethodBuilder GenerateInvocation(TypeBuilder owner, Type interfaceType, MethodInfo overrideMethod, IEnumerable<FieldBuilder> fieldBuilders) { var result = owner.DefineMethod ( overrideMethod.Name, MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot, overrideMethod.ReturnType, overrideMethod.GetParameters().OrderBy(p => p.Position).Select(t => t.ParameterType).ToArray() ); result.SetImplementationFlags(MethodImplAttributes.AggressiveInlining); var generator = result.GetILGenerator(); var fieldName = LibraryInterfaceMapper.GetFieldNameForMethodInfo(overrideMethod); var field = fieldBuilders.First(f => f.Name == fieldName); var parameters = overrideMethod.GetParameters(); OnInvokeBegin(owner, interfaceType, generator, overrideMethod); generator.Emit(OpCodes.Ldarg_0); // this generator.Emit(OpCodes.Ldfld, field); // MethodNameProc _glMethodName. Initialized by constructor. foreach (var item in parameters.Where(p => !p.IsRetval).Select((p, i) => new { Type = p, Index = i })) { generator.Emit(OpCodes.Ldarg, item.Index + 1); } generator.EmitCall(OpCodes.Callvirt, field.FieldType.GetMethod("Invoke"), null); OnInvokeEnd(owner, interfaceType, generator, overrideMethod); generator.Emit(OpCodes.Ret); owner.DefineMethodOverride(result, overrideMethod); return result; }
private static void ImplementAddInterceptionBehavior(TypeBuilder typeBuilder, FieldInfo proxyInterceptorPipelineField) { // Declaring method builder // Method attributes const MethodAttributes MethodAttributes = MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot; MethodBuilder methodBuilder = typeBuilder.DefineMethod( "Microsoft.Practices.Unity.InterceptionExtension.IInterceptingProxy.AddInterceptionBehavior", MethodAttributes); // Setting return type methodBuilder.SetReturnType(typeof(void)); // Adding parameters methodBuilder.SetParameters(typeof(IInterceptionBehavior)); // Parameter method methodBuilder.DefineParameter(1, ParameterAttributes.None, "interceptor"); ILGenerator il = methodBuilder.GetILGenerator(); // Writing body il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, proxyInterceptorPipelineField); il.Emit(OpCodes.Ldarg_1); il.EmitCall(OpCodes.Callvirt, InterceptionBehaviorPipelineMethods.Add, null); il.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(methodBuilder, IInterceptingProxyMethods.AddInterceptionBehavior); }
public override MethodBuilder Generate(TypeBuilder typeBuilder) { var methodBuilder = GenerateMethod(typeBuilder); typeBuilder.DefineMethodOverride(methodBuilder, _methodMetadata.Method); return methodBuilder; }
public override void CreateDeclarations(System.Reflection.Emit.TypeBuilder typeBuilder) { this.BaseMethod = typeBuilder.BaseType.GetMethods().OfType <MethodInfo>() .Where(p => p.Name == this.MemberName) .FirstOrDefault(p => p.ReturnType == this.MemberType && p.GetParameters().Length == this.ArgumentTypes.Count && p.GetParameters().Select((x, i) => new { Index = i, Type = x.ParameterType }).All(x => this.ArgumentTypes[x.Index] == x.Type)); if (BaseMethod != null && !BaseMethod.IsVirtual) { throw new MemberCreationException(this.MemberName, "The method has to be declared virtual on the base class."); } else if (BaseMethod != null) { IsOverride = true; } MethodAttributes methodAttributes = MethodAttributes.Public; if (IsProtected) { methodAttributes = MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.HideBySig; } else { methodAttributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.HideBySig; } var implementationAttributes = MethodAttributes.Private | MethodAttributes.SpecialName | MethodAttributes.HideBySig; Method = typeBuilder.DefineMethod(this.MemberName, methodAttributes); ImplementationMethod = typeBuilder.DefineMethod(string.Format("{0}_Implementation", this.MemberName), implementationAttributes); var genericParameters = GetGenericArguments().ToList(); if (genericParameters.Any()) { this._genericParameters.AddRange(Method.DefineGenericParameters(genericParameters.ToArray())); this._genericImplementationParameters.AddRange(ImplementationMethod.DefineGenericParameters(genericParameters.ToArray())); } this.Method.SetReturnType(TypeLookup(this.MemberType)); this.Method.SetParameters(TypeLookup(this.ArgumentTypes).ToArray()); this.ImplementationMethod.SetReturnType(ImplementationTypeLookup(this.MemberType)); this.ImplementationMethod.SetParameters(ImplementationTypeLookup(this.ArgumentTypes).ToArray()); if (IsOverride) { typeBuilder.DefineMethodOverride(this.Method, this.BaseMethod); } }
private void EmitOverride_GetCacheType(TypeBuilder typeBuilder, string overrideName, FieldBuilder fb_cacheType) { MethodBuilder mb = typeBuilder.DefineMethod(overrideName, MethodAttributes.Family | MethodAttributes.Virtual); mb.SetReturnType(typeof(Type)); typeBuilder.DefineMethodOverride(mb, typeof(ReadMapper).GetMethod(overrideName, BindingFlags.NonPublic | BindingFlags.Instance)); ILGenerator il = mb.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, fb_cacheType); il.Emit(OpCodes.Ret); }
public void ImplementProxy(TypeBuilder b) { var dynamicProxyType = typeof(IDynamicProxy); b.AddInterfaceImplementation(dynamicProxyType); _fieldBuilder = b.DefineField("__interceptor", typeof(IMethodInterceptor), FieldAttributes.Private); const MethodAttributes attributes = MethodAttributes.SpecialName | MethodAttributes.VtableLayoutMask | MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Public; var getMethodBuilder = b.DefineMethod("get_Interceptor", attributes, CallingConventions.HasThis, typeof(IMethodInterceptor), new Type[0]); getMethodBuilder.SetImplementationFlags(MethodImplAttributes.IL); var w = getMethodBuilder.GetILGenerator(); w.Emit(OpCodes.Ldarg_0); w.Emit(OpCodes.Ldfld, _fieldBuilder); w.Emit(OpCodes.Ret); var setMethodBuilder = b.DefineMethod("set_Interceptor", attributes, CallingConventions.HasThis, typeof(void), new Type[] { typeof(IMethodInterceptor) }); setMethodBuilder.SetImplementationFlags(MethodImplAttributes.IL); w = setMethodBuilder.GetILGenerator(); w.Emit(OpCodes.Ldarg_0); w.Emit(OpCodes.Ldarg_1); w.Emit(OpCodes.Stfld, _fieldBuilder); w.Emit(OpCodes.Ret); b.DefineMethodOverride(setMethodBuilder, dynamicProxyType.GetMethod("set_Interceptor")); b.DefineMethodOverride(getMethodBuilder, dynamicProxyType.GetMethod("get_Interceptor")); }
private static MethodBuilder DefineMethod(TypeBuilder newType, Type interfaceType, string methodName) { MethodInfo getInterfaceMethodInfo = interfaceType.GetMethod(methodName); MethodBuilder getMethod = newType.DefineMethod( string.Concat(interfaceType.Name, '.', getInterfaceMethodInfo.Name), MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Virtual, CallingConventions.Standard, getInterfaceMethodInfo.ReturnType, ClassWrappers.GetParameterTypes(getInterfaceMethodInfo.GetParameters())); newType.DefineMethodOverride(getMethod, getInterfaceMethodInfo); return getMethod; }
private static void WriteIsAuthorized(Type parentType, TypeBuilder builder) { MethodInfo protectedMethod = parentType.GetMethod("AuthorizeCore", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod); MethodBuilder implementedMethod = builder.DefineMethod("IsAuthorized", MethodAttributes.Public | MethodAttributes.Virtual, typeof(bool), new[] { typeof(HttpContextBase) }); ILGenerator il = implementedMethod.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Call, protectedMethod); il.Emit(OpCodes.Ret); MethodInfo interfaceMethod = authorizeAttributeType.GetMethod("IsAuthorized", BindingFlags.Public | BindingFlags.Instance); builder.DefineMethodOverride(implementedMethod, interfaceMethod); }
private static MethodBuilder DefineMethod(TypeBuilder newType, Type interfaceType, string methodName, Type[] parameterTypes) { MethodInfo getMethod = interfaceType.GetMethod(methodName, parameterTypes); if (getMethod == null) return null; MethodBuilder builder = newType.DefineMethod( string.Concat(interfaceType.Name, '.', getMethod.Name), MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Virtual, getMethod.ReturnType, parameterTypes); newType.DefineMethodOverride(builder, getMethod); return builder; }
private static MethodBuilder DefinePropertyGetMethod(TypeBuilder newType, string propertyName, Type interfaceType) { MethodInfo getPropertyMethod = interfaceType.GetProperty(propertyName).GetGetMethod(); if (getPropertyMethod == null) return null; MethodBuilder builder = newType.DefineMethod( string.Concat(interfaceType.Name, '.', getPropertyMethod.Name), MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Virtual, getPropertyMethod.ReturnType, Type.EmptyTypes); newType.DefineMethodOverride(builder, getPropertyMethod); return builder; }
private static void BuildIProxyTargetPropertyMethod( TypeBuilder proxyBuilder, Type targetType, Type iProxyType, FieldBuilder wrappedObject, TypeDebugging debug) { var attributes = MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Private; var method = proxyBuilder.DefineMethod(GetTargetMethod, attributes, targetType, Type.EmptyTypes); proxyBuilder.DefineMethodOverride(method, iProxyType.GetProperty(TargetProperty).GetGetMethod()); using (var generator = debug.GetMethodDebugging(method)) { generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldfld, wrappedObject); generator.Emit(OpCodes.Ret); } }
public override MethodBuilder Generate(TypeBuilder typeBuilder) { var targetMethodGenerator = new TargetedInvocationMethodGenerator( _methodMetadata, _targetField); var targetMethod = targetMethodGenerator.Generate(typeBuilder); var methodBuilder = GenerateMethod( typeBuilder, _methodMetadata, _dispatcherField, _methodInfoField, targetMethod); if (_methodMetadata.IsExplicitInterfaceImplementation) { typeBuilder.DefineMethodOverride(methodBuilder, _methodMetadata.Method); } return methodBuilder; }
/// <summary> /// CreateMethod /// </summary> /// <param name="methodInfo"></param> /// <param name="typeBuilder"></param> private static void CreateMethod(this MethodInfo methodInfo, System.Reflection.Emit.TypeBuilder typeBuilder) { // Define the method var methodBuilder = typeBuilder.DefineMethod(methodInfo.Name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.Virtual, methodInfo.ReturnType, methodInfo.GetParameters().Select(parameterInfo => parameterInfo.ParameterType).ToArray()); // The ILGenerator class is used to put op-codes (similar to assembly) into the method // ReSharper disable once InconsistentNaming var IL = methodBuilder.GetILGenerator(); // If there's a return type, create a default value or null to return if (methodInfo.ReturnType != typeof(void)) { var localBuilder = IL.DeclareLocal(methodInfo.ReturnType); // this declares the local object, // int, long, float, ect IL.Emit(OpCodes.Ldloc, localBuilder); // load the value on the stack to return } IL.Emit(OpCodes.Ret); // return // We need to associate our new type's method with the setter method in the interface typeBuilder.DefineMethodOverride(methodBuilder, methodInfo); }
public static void Implement (TypeBuilder typeB, Type iface) { typeB.AddInterfaceImplementation (iface); foreach (MethodInfo declMethod in iface.GetMethods ()) { MethodBuilder method_builder = typeB.DefineMethod (declMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual, declMethod.ReturnType, Mapper.GetTypes (ArgDirection.In, declMethod.GetParameters ())); ILGenerator ilg = method_builder.GetILGenerator (); //Mapper.GetTypes (ArgDirection.In, declMethod.GetParameters ()) ParameterInfo[] delegateParms = declMethod.GetParameters (); Type[] hookupParms = new Type[delegateParms.Length+1]; hookupParms[0] = typeof (BusObject); for (int i = 0; i < delegateParms.Length ; i++) hookupParms[i+1] = delegateParms[i].ParameterType; GenHookupMethod (ilg, declMethod, sendMethodCallMethod, Mapper.GetInterfaceName (iface), declMethod.Name, hookupParms); typeB.DefineMethodOverride (method_builder, declMethod); } }
public static MethodBuilder CreateMethod(TypeBuilder typeBuilder, MethodInfo method) { var scope = method.IsPublic ? MethodAttributes.Public : MethodAttributes.Family; var parameters = method.GetParameters(); var parameterTypes = parameters.Select(p => p.ParameterType) .ToArray(); var methodBuilder = typeBuilder.DefineMethod(method.Name, scope | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig, method.CallingConvention, method.ReturnType, parameterTypes); foreach (var parameter in parameters) { methodBuilder.DefineParameter(parameter.Position + 1, parameter.Attributes, parameter.Name); } typeBuilder.DefineMethodOverride(methodBuilder, method); return methodBuilder; }
public static void Implement (TypeBuilder typeB, Type iface) { typeB.AddInterfaceImplementation (iface); foreach (MethodInfo declMethod in iface.GetMethods ()) { ParameterInfo[] parms = declMethod.GetParameters (); Type[] parmTypes = new Type[parms.Length]; for (int i = 0 ; i < parms.Length ; i++) parmTypes[i] = parms[i].ParameterType; MethodAttributes attrs = declMethod.Attributes ^ MethodAttributes.Abstract; MethodBuilder method_builder = typeB.DefineMethod (declMethod.Name, attrs, declMethod.ReturnType, parmTypes); typeB.DefineMethodOverride (method_builder, declMethod); //define in/out/ref/name for each of the parameters for (int i = 0; i < parms.Length ; i++) method_builder.DefineParameter (i, parms[i].Attributes, parms[i].Name); ILGenerator ilg = method_builder.GetILGenerator (); GenHookupMethod (ilg, declMethod, sendMethodCallMethod, Mapper.GetInterfaceName (iface), declMethod.Name); } }
private void BuildUnproxiedMethod(string wrapperName, TypeBuilder typeBuilder, MethodInfo method) { wrapperName = method.Name; ParameterInfo[] parameterInfos = method.GetParameters(); Type[] parameterTypes = new Type[parameterInfos.Length]; for (int i = 0; i < parameterInfos.Length; i++) parameterTypes[i] = parameterInfos[i].ParameterType; Type returnType = method.ReturnType; MethodBuilder methodBuilder = typeBuilder.DefineMethod(wrapperName, MethodAttributes.NewSlot | MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig, CallingConventions.Standard, returnType, parameterTypes); typeBuilder.DefineMethodOverride(methodBuilder, method); for (int i = 0; i < parameterInfos.Length; i++) { methodBuilder.DefineParameter(i + 1, parameterInfos[i].Attributes, parameterInfos[i].Name); } ILGenerator il = methodBuilder.GetILGenerator(); // il.EmitWriteLine("enter " + wrapperName) ; il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, that); for (int i = 0; i < parameterInfos.Length; i++) il.Emit(OpCodes.Ldarg, i + 1); il.Emit(OpCodes.Callvirt, method); il.Emit(OpCodes.Ret); }
/// <summary> /// Adds a new method to the class, with the given name and method signature. /// </summary> /// <param name="name">The name of the method. name cannot contain embedded nulls. </param> /// <param name="methodInfoDeclaration">The method whose declaration is to be used.</param> /// <param name="attributes">The attributes of the method. </param> /// <returns>The defined method.</returns> public MethodBuilderHelper DefineMethod( string name, MethodInfo methodInfoDeclaration, MethodAttributes attributes) { if (methodInfoDeclaration == null) { throw new ArgumentNullException("methodInfoDeclaration"); } MethodBuilderHelper method; ParameterInfo[] pi = methodInfoDeclaration.GetParameters(); Type[] parameters = new Type[pi.Length]; // When a method contains a generic parameter we need to replace all // generic types from methodInfoDeclaration with local ones. // if (methodInfoDeclaration.ContainsGenericParameters) { method = new MethodBuilderHelper(this, _typeBuilder.DefineMethod(name, attributes, methodInfoDeclaration.CallingConvention), false); Type[] genArgs = methodInfoDeclaration.GetGenericArguments(); GenericTypeParameterBuilder[] genParams = method.MethodBuilder.DefineGenericParameters( Array.ConvertAll <Type, string>(genArgs, delegate(Type t) { return(t.Name); })); // Copy parameter constraints. // List <Type> interfaceConstraints = null; for (int i = 0; i < genParams.Length; i++) { genParams[i].SetGenericParameterAttributes(genArgs[i].GenericParameterAttributes); foreach (Type constraint in genArgs[i].GetGenericParameterConstraints()) { if (constraint.IsClass) { genParams[i].SetBaseTypeConstraint(constraint); } else { if (interfaceConstraints == null) { interfaceConstraints = new List <Type>(); } interfaceConstraints.Add(constraint); } } if (interfaceConstraints != null && interfaceConstraints.Count > 0) { genParams[i].SetInterfaceConstraints(interfaceConstraints.ToArray()); interfaceConstraints.Clear(); } } for (int i = 0; i < pi.Length; i++) { parameters[i] = TypeHelper.TranslateGenericParameters(pi[i].ParameterType, genParams); } method.MethodBuilder.SetParameters(parameters); method.MethodBuilder.SetReturnType(TypeHelper.TranslateGenericParameters( methodInfoDeclaration.ReturnType, genParams)); // Now its safe to add a custom attribute. // method.MethodBuilder.SetCustomAttribute(method.Type.Assembly.BLToolkitAttribute); } else { for (int i = 0; i < pi.Length; i++) { parameters[i] = pi[i].ParameterType; } method = DefineMethod( name, attributes, methodInfoDeclaration.CallingConvention, methodInfoDeclaration.ReturnType, parameters); } // Compiler overrides methods only for interfaces. We do the same. // If we wanted to override virtual methods, then methods should've had // MethodAttributes.VtableLayoutMask attribute // and the following condition should've been used below: // if ((methodInfoDeclaration is FakeMethodInfo) == false) // if (methodInfoDeclaration.DeclaringType.IsInterface && !(methodInfoDeclaration is FakeMethodInfo)) { OverridenMethods.Add(methodInfoDeclaration, method.MethodBuilder); _typeBuilder.DefineMethodOverride(method.MethodBuilder, methodInfoDeclaration); } method.OverriddenMethod = methodInfoDeclaration; for (int i = 0; i < pi.Length; i++) { method.MethodBuilder.DefineParameter(i + 1, pi[i].Attributes, pi[i].Name); } return(method); }
private static void DefineSetMethod(TypeBuilder newType, PropertyBuilder propertyBuilder, FieldInfo fieldBuilder, PropertyInfo property) { var setMethod = property.GetSetMethod(); if (setMethod == null) return; var methodBuilder = newType.DefineMethod(setMethod.Name, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Virtual, null, new[] {property.PropertyType}); var ilg = methodBuilder.GetILGenerator(); ilg.Emit(OpCodes.Ldarg_0); ilg.Emit(OpCodes.Ldarg_1); ilg.Emit(OpCodes.Stfld, fieldBuilder); ilg.Emit(OpCodes.Ret); propertyBuilder.SetSetMethod(methodBuilder); var methodInfo = methodBuilder.GetBaseDefinition(); newType.DefineMethodOverride(methodInfo, setMethod); }
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); }
private static MethodBuilder MakeMethod(TypeBuilder typeBuilder, MethodInfo method, Boolean createPublic) { Int32 methodNum = DynamicProxy.Register(method); Type[] paramTypes = ToTypes(method.GetParameters()); Int32 paramNum = paramTypes.Length; Boolean[] paramsByRef = new Boolean[paramNum]; MethodBuilder b; String name; MethodAttributes methodAttr; if (createPublic) { name = method.Name; methodAttr = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig; } else { name = method.DeclaringType.FullName + "." + method.Name; methodAttr = MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Final; } b = typeBuilder.DefineMethod(name, methodAttr, method.CallingConvention, method.ReturnType, paramTypes); ILGenerator gen = b.GetILGenerator(); LocalBuilder parameters = gen.DeclareLocal(typeof(Object[])); LocalBuilder result = gen.DeclareLocal(typeof(Object)); LocalBuilder retval = null; if (!method.ReturnType.Equals(typeof(void))) { retval = gen.DeclareLocal(method.ReturnType); } gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, FieldInfo_handler); //this.handler gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldc_I4, methodNum); gen.Emit(OpCodes.Call, MethodInfo_GetMethod); gen.Emit(OpCodes.Ldc_I4, paramNum); gen.Emit(OpCodes.Newarr, typeof(Object)); // new Object[] if (paramNum > 0) { gen.Emit(OpCodes.Stloc, parameters); for (Int32 i = 0; i < paramNum; i++) { gen.Emit(OpCodes.Ldloc, parameters); gen.Emit(OpCodes.Ldc_I4, i); gen.Emit(OpCodes.Ldarg, i + 1); if (paramTypes[i].IsByRef) { paramTypes[i] = paramTypes[i].GetElementType(); if (paramTypes[i] == typeofInt8 || paramTypes[i] == typeofBoolean) { gen.Emit(OpCodes.Ldind_I1); } else if (paramTypes[i] == typeofUInt8) { gen.Emit(OpCodes.Ldind_U1); } else if (paramTypes[i] == typeofInt16) { gen.Emit(OpCodes.Ldind_I2); } else if (paramTypes[i] == typeofUInt16 || paramTypes[i] == typeofChar) { gen.Emit(OpCodes.Ldind_U2); } else if (paramTypes[i] == typeofInt32) { gen.Emit(OpCodes.Ldind_I4); } else if (paramTypes[i] == typeofUInt32) { gen.Emit(OpCodes.Ldind_U4); } else if (paramTypes[i] == typeofInt64 || paramTypes[i] == typeofUInt64) { gen.Emit(OpCodes.Ldind_I8); } else if (paramTypes[i] == typeofSingle) { gen.Emit(OpCodes.Ldind_R4); } else if (paramTypes[i] == typeofDouble) { gen.Emit(OpCodes.Ldind_R8); } else if (paramTypes[i].IsValueType) { gen.Emit(OpCodes.Ldobj, paramTypes[i]); } else { gen.Emit(OpCodes.Ldind_Ref); } paramsByRef[i] = true; } else { paramsByRef[i] = false; } if (paramTypes[i].IsValueType) { gen.Emit(OpCodes.Box, paramTypes[i]); } gen.Emit(OpCodes.Stelem_Ref); } gen.Emit(OpCodes.Ldloc, parameters); } // base.Invoke(this, method, parameters); gen.Emit(OpCodes.Callvirt, DynamicProxy_Invoke); gen.Emit(OpCodes.Stloc, result); for (Int32 i = 0; i < paramNum; i++) { if (paramsByRef[i]) { gen.Emit(OpCodes.Ldarg, i + 1); gen.Emit(OpCodes.Ldloc, parameters); gen.Emit(OpCodes.Ldc_I4, i); gen.Emit(OpCodes.Ldelem_Ref); if (paramTypes[i].IsValueType) { #if NET1 gen.Emit(OpCodes.Unbox, paramTypes[i]); gen.Emit(OpCodes.Ldobj, paramTypes[i]); #else gen.Emit(OpCodes.Unbox_Any, paramTypes[i]); #endif } else { gen.Emit(OpCodes.Castclass, paramTypes[i]); } if (paramTypes[i] == typeofInt8 || paramTypes[i] == typeofUInt8 || paramTypes[i] == typeofBoolean) { gen.Emit(OpCodes.Stind_I1); } else if (paramTypes[i] == typeofInt16 || paramTypes[i] == typeofUInt16 || paramTypes[i] == typeofChar) { gen.Emit(OpCodes.Stind_I2); } else if (paramTypes[i] == typeofInt32 || paramTypes[i] == typeofUInt32) { gen.Emit(OpCodes.Stind_I4); } else if (paramTypes[i] == typeofInt64 || paramTypes[i] == typeofUInt64) { gen.Emit(OpCodes.Stind_I8); } else if (paramTypes[i] == typeofSingle) { gen.Emit(OpCodes.Stind_R4); } else if (paramTypes[i] == typeofDouble) { gen.Emit(OpCodes.Stind_R8); } else if (paramTypes[i].IsValueType) { gen.Emit(OpCodes.Stobj, paramTypes[i]); } else { gen.Emit(OpCodes.Stind_Ref); } } } if (!method.ReturnType.Equals(typeof(void))) { gen.Emit(OpCodes.Ldloc, result); if (method.ReturnType.IsValueType) { #if NET1 gen.Emit(OpCodes.Unbox, method.ReturnType); gen.Emit(OpCodes.Ldobj, method.ReturnType); #else gen.Emit(OpCodes.Unbox_Any, method.ReturnType); #endif } else { gen.Emit(OpCodes.Castclass, method.ReturnType); } gen.Emit(OpCodes.Stloc_S, retval); gen.Emit(OpCodes.Ldloc_S, retval); } gen.Emit(OpCodes.Ret); if (!createPublic) { typeBuilder.DefineMethodOverride(b, method); } return b; }
private static void DefineGetMethod(TypeBuilder newType, PropertyBuilder propertyBuilder, FieldInfo fieldBuilder, PropertyInfo property) { var getMethod = property.GetGetMethod(); var methodBuilder = newType.DefineMethod(getMethod.Name, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Virtual, property.PropertyType, Type.EmptyTypes); var ilg = methodBuilder.GetILGenerator(); ilg.Emit(OpCodes.Ldarg_0); ilg.Emit(OpCodes.Ldfld, fieldBuilder); ilg.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(methodBuilder); var methodInfo = methodBuilder.GetBaseDefinition(); newType.DefineMethodOverride(methodInfo, getMethod); }
// generates this explicit interface method: // public new Interface.Method(param0, param1, ...) { // return base.Method(param0, param1, ...); // } private static void ImplementInterfaceMethod(TypeBuilder newType, MethodInfo interfaceMethod) { var parameters = interfaceMethod.GetParameters(); var parameterTypes = (from p in parameters select p.ParameterType).ToArray(); // based on http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.definemethodoverride.aspx var newMethod = newType.DefineMethod(interfaceMethod.DeclaringType.Name + "." + interfaceMethod.Name, MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, interfaceMethod.ReturnType, parameterTypes); var baseMethod = newType.BaseType.GetMethod(interfaceMethod.Name, parameterTypes); // parameter 0 is 'this', so we start at index 1 for (int i = 0; i < parameters.Length; i++) { newMethod.DefineParameter(i + 1, parameters[i].Attributes, parameters[i].Name); } // load all arguments (including 'this') in proper order, then call and return var ilGen = newMethod.GetILGenerator(); for (int i = 0; i <= parameterTypes.Length; i++) { ilGen.Emit(OpCodes.Ldarg_S, (byte)i); } ilGen.Emit(OpCodes.Call, baseMethod); ilGen.Emit(OpCodes.Ret); // finally, hook the new method up to the interface mapping newType.DefineMethodOverride(newMethod, interfaceMethod); }
/// <summary> /// Generates a GetHashCode method. /// </summary> /// <param name="dynamicType">A <see cref="TypeBuilder"/> to generate a GetHashCode method for.</param> /// <param name="fields">Fields to read in the GetHashCode method.</param> private static void GenerateGetHashCodeMethod(TypeBuilder dynamicType, IEnumerable<FieldBuilder> fields) { MethodBuilder method = dynamicType.DefineMethod("GetHashCode", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual, CallingConventions.Standard, typeof(int), new Type[0]); ILGenerator ilGen = method.GetILGenerator(); Type eqEr = typeof(EqualityComparer<>); LocalBuilder localNum = ilGen.DeclareLocal(typeof(int)); ilGen.Emit(OpCodes.Ldc_I4, new Random(unchecked((int)DateTime.Now.Ticks)).Next(int.MaxValue)); ilGen.Emit(OpCodes.Stloc, localNum); foreach (FieldBuilder field in fields) { ilGen.Emit(OpCodes.Ldc_I4, 0xa5555529); ilGen.Emit(OpCodes.Ldloc, localNum); ilGen.Emit(OpCodes.Mul); Type genericEqer = eqEr.MakeGenericType(field.FieldType); MethodInfo eqDefaultMethod = eqEr.GetProperty("Default", BindingFlags.Static | BindingFlags.Public).GetGetMethod(); MethodInfo genericEqDefaultMethod = TypeBuilder.GetMethod(genericEqer, eqDefaultMethod); ilGen.EmitCall(OpCodes.Call, genericEqDefaultMethod, null); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldfld, field); Type theTofEqualizer = eqEr.GetGenericArguments()[0]; MethodInfo eqEqualsMethod = eqEr.GetMethod("GetHashCode", BindingFlags.Public | BindingFlags.Instance, null, new[] { theTofEqualizer }, null); MethodInfo genericEqEqualsMethod = TypeBuilder.GetMethod(genericEqer, eqEqualsMethod); ilGen.EmitCall(OpCodes.Callvirt, genericEqEqualsMethod, null); ilGen.Emit(OpCodes.Add); ilGen.Emit(OpCodes.Stloc, localNum); } ilGen.Emit(OpCodes.Ldloc, localNum); ilGen.Emit(OpCodes.Ret); dynamicType.DefineMethodOverride(method, typeof(object).GetMethod("GetHashCode", BindingFlags.Public | BindingFlags.Instance)); AddDebuggerHiddenAttribute(method); }
/// <summary> /// Adds a new method to the class, with the given name and method signature. /// </summary> /// <param name="name">The name of the method. name cannot contain embedded nulls. </param> /// <param name="methodInfoDeclaration">The method whose declaration is to be used.</param> /// <param name="attributes">The attributes of the method. </param> /// <returns>The defined method.</returns> public MethodBuilderHelper DefineMethod( string name, MethodInfo methodInfoDeclaration, MethodAttributes attributes) { if (methodInfoDeclaration == null) { throw new ArgumentNullException("methodInfoDeclaration"); } MethodBuilderHelper method; ParameterInfo[] pi = methodInfoDeclaration.GetParameters(); Type[] parameters = new Type[pi.Length]; for (int i = 0; i < pi.Length; i++) { parameters[i] = pi[i].ParameterType; } if (methodInfoDeclaration.ContainsGenericParameters) { method = DefineGenericMethod( name, attributes, methodInfoDeclaration.CallingConvention, methodInfoDeclaration.GetGenericArguments(), methodInfoDeclaration.ReturnType, parameters); } else { method = DefineMethod( name, attributes, methodInfoDeclaration.CallingConvention, methodInfoDeclaration.ReturnType, parameters); } // Compiler overrides methods only for interfaces. We do the same. // If we wanted to override virtual methods, then methods should've had // MethodAttributes.VtableLayoutMask attribute // and the following condition should've been used below: // if ((methodInfoDeclaration is FakeMethodInfo) == false) // if (methodInfoDeclaration.DeclaringType.IsInterface #if !SILVERLIGHT && !(methodInfoDeclaration is FakeMethodInfo) #endif ) { OverriddenMethods.Add(methodInfoDeclaration, method.MethodBuilder); _typeBuilder.DefineMethodOverride(method.MethodBuilder, methodInfoDeclaration); } method.OverriddenMethod = methodInfoDeclaration; for (int i = 0; i < pi.Length; i++) { method.MethodBuilder.DefineParameter(i + 1, pi[i].Attributes, pi[i].Name); } return(method); }
/* * Generates an overriden implementation of method inside myType that delegates * to a function in a Lua table with the same name, if the function exists. If it * doesn't the method calls the base method (or does nothing, in case of interface * implementations). */ private void GenerateMethod(TypeBuilder myType, MethodInfo method, MethodAttributes attributes, int methodIndex, FieldInfo luaTableField, FieldInfo returnTypesField, bool generateBase, out Type[] returnTypes) { var paramInfo = method.GetParameters (); var paramTypes = new Type[paramInfo.Length]; var returnTypesList = new List<Type> (); // Counts out and ref parameters, for later use, // and creates the list of return types int nOutParams = 0; int nOutAndRefParams = 0; var returnType = method.ReturnType; returnTypesList.Add (returnType); for (int i = 0; i < paramTypes.Length; i++) { paramTypes [i] = paramInfo [i].ParameterType; if ((!paramInfo [i].IsIn) && paramInfo [i].IsOut) nOutParams++; if (paramTypes [i].IsByRef) { returnTypesList.Add (paramTypes [i].GetElementType ()); nOutAndRefParams++; } } int[] refArgs = new int[nOutAndRefParams]; returnTypes = returnTypesList.ToArray (); // Generates a version of the method that calls the base implementation // directly, for use by the base field of the table if (generateBase) { var baseMethod = myType.DefineMethod ("__luaInterface_base_" + method.Name, MethodAttributes.Private | MethodAttributes.NewSlot | MethodAttributes.HideBySig, returnType, paramTypes); ILGenerator generatorBase = baseMethod.GetILGenerator (); generatorBase.Emit (OpCodes.Ldarg_0); for (int i = 0; i < paramTypes.Length; i++) generatorBase.Emit (OpCodes.Ldarg, i + 1); generatorBase.Emit (OpCodes.Call, method); if (returnType == typeof(void)) generatorBase.Emit (OpCodes.Pop); generatorBase.Emit (OpCodes.Ret); } // Defines the method var methodImpl = myType.DefineMethod (method.Name, attributes, returnType, paramTypes); // If it's an implementation of an interface tells what method it // is overriding if (myType.BaseType.Equals (typeof(object))) myType.DefineMethodOverride (methodImpl, method); ILGenerator generator = methodImpl.GetILGenerator (); generator.DeclareLocal (typeof(object[])); // original arguments generator.DeclareLocal (typeof(object[])); // with out-only arguments removed generator.DeclareLocal (typeof(int[])); // indexes of out and ref arguments if (!(returnType == typeof(void))) // return value generator.DeclareLocal (returnType); else generator.DeclareLocal (typeof(object)); // Initializes local variables generator.Emit (OpCodes.Ldc_I4, paramTypes.Length); generator.Emit (OpCodes.Newarr, typeof(object)); generator.Emit (OpCodes.Stloc_0); generator.Emit (OpCodes.Ldc_I4, paramTypes.Length - nOutParams + 1); generator.Emit (OpCodes.Newarr, typeof(object)); generator.Emit (OpCodes.Stloc_1); generator.Emit (OpCodes.Ldc_I4, nOutAndRefParams); generator.Emit (OpCodes.Newarr, typeof(int)); generator.Emit (OpCodes.Stloc_2); generator.Emit (OpCodes.Ldloc_1); generator.Emit (OpCodes.Ldc_I4_0); generator.Emit (OpCodes.Ldarg_0); generator.Emit (OpCodes.Ldfld, luaTableField); generator.Emit (OpCodes.Stelem_Ref); // Stores the arguments into the local variables, as needed for (int iArgs = 0, iInArgs = 1, iOutArgs = 0; iArgs < paramTypes.Length; iArgs++) { generator.Emit (OpCodes.Ldloc_0); generator.Emit (OpCodes.Ldc_I4, iArgs); generator.Emit (OpCodes.Ldarg, iArgs + 1); if (paramTypes [iArgs].IsByRef) { if (paramTypes [iArgs].GetElementType ().IsValueType) { generator.Emit (OpCodes.Ldobj, paramTypes [iArgs].GetElementType ()); generator.Emit (OpCodes.Box, paramTypes [iArgs].GetElementType ()); } else generator.Emit (OpCodes.Ldind_Ref); } else { if (paramTypes [iArgs].IsValueType) generator.Emit (OpCodes.Box, paramTypes [iArgs]); } generator.Emit (OpCodes.Stelem_Ref); if (paramTypes [iArgs].IsByRef) { generator.Emit (OpCodes.Ldloc_2); generator.Emit (OpCodes.Ldc_I4, iOutArgs); generator.Emit (OpCodes.Ldc_I4, iArgs); generator.Emit (OpCodes.Stelem_I4); refArgs [iOutArgs] = iArgs; iOutArgs++; } if (paramInfo [iArgs].IsIn || (!paramInfo [iArgs].IsOut)) { generator.Emit (OpCodes.Ldloc_1); generator.Emit (OpCodes.Ldc_I4, iInArgs); generator.Emit (OpCodes.Ldarg, iArgs + 1); if (paramTypes [iArgs].IsByRef) { if (paramTypes [iArgs].GetElementType ().IsValueType) { generator.Emit (OpCodes.Ldobj, paramTypes [iArgs].GetElementType ()); generator.Emit (OpCodes.Box, paramTypes [iArgs].GetElementType ()); } else generator.Emit (OpCodes.Ldind_Ref); } else { if (paramTypes [iArgs].IsValueType) generator.Emit (OpCodes.Box, paramTypes [iArgs]); } generator.Emit (OpCodes.Stelem_Ref); iInArgs++; } } // Gets the function the method will delegate to by calling // the getTableFunction method of class LuaClassHelper generator.Emit (OpCodes.Ldarg_0); generator.Emit (OpCodes.Ldfld, luaTableField); generator.Emit (OpCodes.Ldstr, method.Name); generator.Emit (OpCodes.Call, classHelper.GetMethod ("getTableFunction")); var lab1 = generator.DefineLabel (); generator.Emit (OpCodes.Dup); generator.Emit (OpCodes.Brtrue_S, lab1); // Function does not exist, call base method generator.Emit (OpCodes.Pop); if (!method.IsAbstract) { generator.Emit (OpCodes.Ldarg_0); for (int i = 0; i < paramTypes.Length; i++) generator.Emit (OpCodes.Ldarg, i + 1); generator.Emit (OpCodes.Call, method); if (returnType == typeof(void)) generator.Emit (OpCodes.Pop); generator.Emit (OpCodes.Ret); generator.Emit (OpCodes.Ldnull); } else generator.Emit (OpCodes.Ldnull); var lab2 = generator.DefineLabel (); generator.Emit (OpCodes.Br_S, lab2); generator.MarkLabel (lab1); // Function exists, call using method callFunction of LuaClassHelper generator.Emit (OpCodes.Ldloc_0); generator.Emit (OpCodes.Ldarg_0); generator.Emit (OpCodes.Ldfld, returnTypesField); generator.Emit (OpCodes.Ldc_I4, methodIndex); generator.Emit (OpCodes.Ldelem_Ref); generator.Emit (OpCodes.Ldloc_1); generator.Emit (OpCodes.Ldloc_2); generator.Emit (OpCodes.Call, classHelper.GetMethod ("callFunction")); generator.MarkLabel (lab2); // Stores the function return value if (returnType == typeof(void)) { generator.Emit (OpCodes.Pop); generator.Emit (OpCodes.Ldnull); } else if (returnType.IsValueType) { generator.Emit (OpCodes.Unbox, returnType); generator.Emit (OpCodes.Ldobj, returnType); } else generator.Emit (OpCodes.Castclass, returnType); generator.Emit (OpCodes.Stloc_3); // Sets return values of out and ref parameters for (int i = 0; i < refArgs.Length; i++) { generator.Emit (OpCodes.Ldarg, refArgs [i] + 1); generator.Emit (OpCodes.Ldloc_0); generator.Emit (OpCodes.Ldc_I4, refArgs [i]); generator.Emit (OpCodes.Ldelem_Ref); if (paramTypes [refArgs [i]].GetElementType ().IsValueType) { generator.Emit (OpCodes.Unbox, paramTypes [refArgs [i]].GetElementType ()); generator.Emit (OpCodes.Ldobj, paramTypes [refArgs [i]].GetElementType ()); generator.Emit (OpCodes.Stobj, paramTypes [refArgs [i]].GetElementType ()); } else { generator.Emit (OpCodes.Castclass, paramTypes [refArgs [i]].GetElementType ()); generator.Emit (OpCodes.Stind_Ref); } } // Returns if (!(returnType == typeof(void))) generator.Emit (OpCodes.Ldloc_3); generator.Emit (OpCodes.Ret); }
private static void ImplementInterfaceMethod(TypeBuilder newType, MethodInfo interfaceMethod) { ParameterInfo[] parameters = interfaceMethod.GetParameters(); Type[] parameterTypes = new Type[parameters.Length]; for (int idx = 0; idx < parameters.Length; idx++) parameterTypes[idx] = parameters[idx].ParameterType; MethodBuilder newMethod = newType.DefineMethod( interfaceMethod.DeclaringType.Name + "." + interfaceMethod.Name, MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, interfaceMethod.ReturnType, parameterTypes ); MethodInfo baseMethod = newType.BaseType.GetMethod(interfaceMethod.Name, parameterTypes); for (int i = 0; i < parameters.Length; i++) newMethod.DefineParameter(i + 1, parameters[i].Attributes, parameters[i].Name); ILGenerator ilGen = newMethod.GetILGenerator(); for (int i = 0; i <= parameterTypes.Length; i++) ilGen.Emit(OpCodes.Ldarg_S, (byte)i); ilGen.Emit(OpCodes.Call, baseMethod); ilGen.Emit(OpCodes.Ret); newType.DefineMethodOverride(newMethod, interfaceMethod); }
private static void GenerateThunk(TypeBuilder tb, MethodInfo method) { ParameterInfo[] pi = method.GetParameters(); int count = pi.Length; int argc = count - 1; Type[] args = new Type[count]; for (int i = 0; i < count; i++) { args[i] = pi[i].ParameterType; } MethodBuilder mb = tb.DefineMethod( method.Name, MethodAttributes.Public | MethodAttributes.Virtual, method.ReturnType, args ); // Build the method signature for the actual native function. // This is essentially the signature of the wrapper method // minus the first argument (the passed in function pointer). Type[] nargs = new Type[argc]; for (int i = 1; i < count; i++) { nargs[(i - 1)] = args[i]; } // IL generation: the (implicit) first argument of the method // is the 'this' pointer and the second is the function pointer. // This code pushes the real args onto the stack, followed by // the function pointer, then the calli opcode to make the call. ILGenerator il = mb.GetILGenerator(); for (int i = 0; i < argc; i++) { il.Emit(OpCodes.Ldarg_S, (i + 2)); } il.Emit(OpCodes.Ldarg_1); il.EmitCalli(OpCodes.Calli, CallingConvention.Cdecl, method.ReturnType, nargs ); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(mb, method); return; }
/// <summary> /// Generate a ToString method. /// </summary> /// <param name="dynamicType">A <see cref="TypeBuilder"/> to generate a ToString method for.</param> /// <param name="propertyNames">The names of the properties of the type.</param> /// <param name="fields">Fields to read in the ToString method.</param> private static void GenerateToStringMethod(TypeBuilder dynamicType, string[] propertyNames, FieldBuilder[] fields) { MethodBuilder method = dynamicType.DefineMethod("ToString", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual, CallingConventions.Standard, typeof(string), new Type[0]); ILGenerator ilGen = method.GetILGenerator(); LocalBuilder localBuilder = ilGen.DeclareLocal(typeof(StringBuilder)); MethodInfo appendObject = typeof(StringBuilder).GetMethod("Append", BindingFlags.Instance | BindingFlags.Public, null, new[] { typeof(object) }, null); MethodInfo appendString = typeof(StringBuilder).GetMethod("Append", BindingFlags.Instance | BindingFlags.Public, null, new[] { typeof(string) }, null); MethodInfo sbToString = typeof(object).GetMethod("ToString", BindingFlags.Instance | BindingFlags.Public, null, new Type[0], null); ilGen.Emit(OpCodes.Newobj, typeof(StringBuilder).GetConstructor(new Type[0])); ilGen.Emit(OpCodes.Stloc, localBuilder); ilGen.Emit(OpCodes.Ldloc, localBuilder); ilGen.Emit(OpCodes.Ldstr, "{ "); ilGen.EmitCall(OpCodes.Callvirt, appendString, null); ilGen.Emit(OpCodes.Pop); bool first = true; for (int i = 0; i < fields.Length; i++) { FieldBuilder field = fields[i]; ilGen.Emit(OpCodes.Ldloc, localBuilder); ilGen.Emit(OpCodes.Ldstr, string.Concat(first ? "" : ", ", propertyNames[i], " = ")); ilGen.EmitCall(OpCodes.Callvirt, appendString, null); ilGen.Emit(OpCodes.Pop); ilGen.Emit(OpCodes.Ldloc, localBuilder); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldfld, field); ilGen.Emit(OpCodes.Box, field.FieldType); ilGen.EmitCall(OpCodes.Callvirt, appendObject, null); ilGen.Emit(OpCodes.Pop); first = false; } ilGen.Emit(OpCodes.Ldloc, localBuilder); ilGen.Emit(OpCodes.Ldstr, " }"); ilGen.EmitCall(OpCodes.Callvirt, appendString, null); ilGen.Emit(OpCodes.Pop); ilGen.Emit(OpCodes.Ldloc, localBuilder); ilGen.EmitCall(OpCodes.Callvirt, sbToString, null); ilGen.Emit(OpCodes.Ret); dynamicType.DefineMethodOverride(method, typeof(object).GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance)); AddDebuggerHiddenAttribute(method); }
private static ILGen/*!*/ DefineMethodOverride(TypeBuilder/*!*/ tb, MethodInfo/*!*/ decl, out MethodBuilder/*!*/ impl) { impl = tb.DefineMethod( decl.Name, decl.Attributes & ~(MethodAttributes.Abstract | MethodAttributes.ReservedMask), decl.ReturnType, ReflectionUtils.GetParameterTypes(decl.GetParameters()) ); tb.DefineMethodOverride(impl, decl); return new ILGen(impl.GetILGenerator()); }
/// <summary> /// Generates a method on our <see cref="TypeBuilder"/> for the specified <see cref="MethodInfo"/> /// </summary> /// <param name="tb">The <see cref="TypeBuilder"/> we're generating our type with.</param> /// <param name="mi">The <see cref="MethodInfo"/> which represents the "template" method.</param> /// <param name="dllName">The path to the DLL that we'll put in the <see cref="DllImportAttribute"/>.</param> private static void GenerateMethod(TypeBuilder tb, MethodInfo mi, string dllName) { // These are all the parameters in our method List<ParameterInfo> pis = new List<ParameterInfo>(mi.GetParameters()); // We need to keep the parameter types and attributes in a separate array. Type[] ptypes = new Type[pis.Count]; ParameterAttributes[] attrs = new ParameterAttributes[pis.Count]; for (int i = 0; i < pis.Count; i++) { ptypes[i] = pis[i].ParameterType; attrs[i] = pis[i].Attributes; } // We actually need to create TWO methods - one for the interface implementation, and one for the // P/Invoke declaration. We'll create the P/Invoke definition first. MethodBuilder smb = tb.DefineMethod( mi.Name, // The name is the same as the interface name // P/Invoke methods need special attributes... MethodAttributes.Static | MethodAttributes.Private | MethodAttributes.HideBySig, mi.ReturnType, ptypes); // Get the type of the DllImportAttribute, which we'll attach to this method Type diaType = typeof (DllImportAttribute); // Create a CustomAttributeBuilder for the DLLImportAttribute, specifying the constructor that takes a string argument. ConstructorInfo ctor = diaType.GetConstructor(new Type[] { typeof(string) }); CustomAttributeBuilder cab = new CustomAttributeBuilder(ctor, new object[] { dllName }); // Assign the DllImport attribute to the smb smb.SetCustomAttribute(cab); // Also, any attributes on the actual parameters need to be copied to the P/Invoke declaration as well. for (int i = 0; i < attrs.Length; i++) { smb.DefineParameter(i + 1, attrs[i], pis[i].Name); } // Now create the interface implementation method MethodBuilder mb = tb.DefineMethod( "IFbClient." + mi.Name, // We use the standard "Interface.Method" to do an explicit interface implementation MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, mi.ReturnType, ptypes); // Also, any attributes on the actual parameters need to be copied to the P/Invoke declaration as well. for (int i = 0; i < attrs.Length; i++) { mb.DefineParameter(i + 1, attrs[i], pis[i].Name); } // We need to generate a little IL here to actually call the P/Invoke declaration. Luckily for us, since we're just // going to pass our parameters to the P/Invoke method as-is, we don't need to muck with the eval stack ;-) ILGenerator il = mb.GetILGenerator(); for (int i = 1; i <= pis.Count; i++) { if (i == 1) { il.Emit(OpCodes.Ldarg_1); } else if (i == 2) { il.Emit(OpCodes.Ldarg_2); } else if (i == 3) { il.Emit(OpCodes.Ldarg_3); } else { il.Emit(OpCodes.Ldarg_S, (short)i); } } il.EmitCall(OpCodes.Call, smb, null); il.Emit(OpCodes.Ret); // Define the fact that our IFbClient.Method is the explicit interface implementation of that method tb.DefineMethodOverride(mb, mi); }
private static ILGen/*!*/ DefinePrivateInterfaceMethodOverride(TypeBuilder/*!*/ tb, MethodInfo/*!*/ decl, out MethodBuilder/*!*/ impl) { string name = decl.DeclaringType.Name + "." + decl.Name; //MethodAttributes attributes = decl.Attributes & ~(MethodAttributes.Abstract | MethodAttributes.ReservedMask | MethodAttributes.MemberAccessMask) // | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Private; MethodAttributes attributes = decl.Attributes & ~(MethodAttributes.Abstract | MethodAttributes.Public); attributes |= MethodAttributes.NewSlot | MethodAttributes.Final; impl = tb.DefineMethod( name, attributes, decl.ReturnType, ReflectionUtils.GetParameterTypes(decl.GetParameters()) ); tb.DefineMethodOverride(impl, decl); return new ILGen(impl.GetILGenerator()); }
/// <summary> /// Compiles the type that is being built and returns its run-time Type. /// If you want to create instances directly, see the GetConstructorDelegate. /// </summary> public Type Compile() { if (_compiledType == null) { _CheckThread(); _delegates = new Delegate[_methods.Count]; var methodBuilders = new Dictionary <string, MethodBuilder>(); int index = -1; foreach (var method in _methods) { index++; var methodBuilder = _Compile(method, index); methodBuilders[method.Name] = methodBuilder; } foreach (var property in _properties.Values) { string name = property.Name; var propertyBuilder = _type.DefineProperty(name, PropertyAttributes.None, property.PropertyType, Type.EmptyTypes); propertyBuilder.SetGetMethod(methodBuilders["get_" + name]); propertyBuilder.SetSetMethod(methodBuilders["set_" + name]); } foreach (var eventInfo in _events.Values) { string name = eventInfo.Name; var eventBuilder = _type.DefineEvent(name, EventAttributes.None, eventInfo.Type); string addName = "add_" + name; string removeName = "remove_" + name; var addMethod = methodBuilders[addName]; var removeMethod = methodBuilders[removeName]; eventBuilder.SetAddOnMethod(addMethod); eventBuilder.SetRemoveOnMethod(removeMethod); foreach (var interfaceType in _interfaceTypes) { var method = interfaceType.GetMethod(addName); if (method != null) { _type.DefineMethodOverride(addMethod, method); } method = interfaceType.GetMethod(removeName); if (method != null) { _type.DefineMethodOverride(removeMethod, method); } } } var compiledType = _type.CreateType(); var thisExpression = Expression.Parameter(compiledType, "this"); var fields = _fields.ToArray(); foreach (var fieldPair in fields) { var leftPair = fieldPair.Key; var field = leftPair.Key; var rightPair = fieldPair.Value; string fieldName = rightPair.Value; var expression = Expression.MakeMemberAccess(thisExpression, compiledType.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic)); _fields[leftPair] = new KeyValuePair <MemberExpression, string>(expression, fieldName); } index = -1; foreach (var method in _methods) { index++; if (method._respectVisibility) { continue; } if (!method.IsStatic) { var firstParameter = method._parameters.Keys.First(); method._parameters[firstParameter] = thisExpression; } var compiledMethod = method._Compile(null, null); _delegates[index] = compiledMethod; } var delegatesField = compiledType.GetField(".delegates", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); delegatesField.SetValue(null, _delegates); _compiledType = compiledType; } return(_compiledType); }