methodbuilder.cs

来自「没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没」· CS 代码 · 共 610 行

CS
610
字号
/* * MethodBuilder.cs - Implementation of the *		"System.Reflection.Emit.MethodBuilder" class. * * Copyright (C) 2002  Southern Storm Software, Pty Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */namespace System.Reflection.Emit{#if CONFIG_REFLECTION_EMITusing System;using System.Security;using System.Text;using System.Reflection;using System.Globalization;using System.Security.Permissions;using System.Runtime.InteropServices;using System.Runtime.CompilerServices;public sealed class MethodBuilder : MethodInfo, IClrProgramItem, IDetachItem{	// Internal state.	internal TypeBuilder type;	private IntPtr privateData;	private bool bodySet;	private bool initLocals;	private byte[] explicitBody;	private ILGenerator ilGenerator;	private Type returnType;	private ParameterBuilder returnBuilder;	private SignatureHelper helper;	internal int numParams;	// Constructor.	internal MethodBuilder(TypeBuilder type, String name,						   MethodAttributes attributes,						   CallingConventions callingConvention,						   Type returnType, Type[] parameterTypes)			{				// Validate the parameters.				if(name == null)				{					throw new ArgumentNullException("name");				}				else if(name == String.Empty)				{					throw new ArgumentException(_("Emit_NameEmpty"));				}				if(returnType == null)				{					returnType = typeof(void);				}				if((attributes & MethodAttributes.Static) == 0)				{					callingConvention |= CallingConventions.HasThis;				}				else if((attributes & MethodAttributes.Virtual) != 0)				{					throw new ArgumentException						(_("Emit_BothStaticAndVirtual"));				}				if((type.Attributes & TypeAttributes.ClassSemanticsMask)						== TypeAttributes.Interface &&				   (attributes & MethodAttributes.SpecialName) == 0)				{					if((attributes & (MethodAttributes.Virtual |									  MethodAttributes.Abstract))						!= (MethodAttributes.Virtual |							MethodAttributes.Abstract))					{						throw new ArgumentException							(_("Emit_InterfaceMethodAttrs"));					}				}				// Set the local state.				this.type = type;				this.bodySet = false;				this.initLocals = true;				this.explicitBody = null;				this.ilGenerator = null;				this.returnType = returnType;				this.returnBuilder = null;				this.numParams = (parameterTypes != null									? parameterTypes.Length : 0);				// Register this item to be detached later.				type.module.assembly.AddDetach(this);				// Create the method signature.				helper = SignatureHelper.GetMethodSigHelper						(type.module, callingConvention,						 (CallingConvention)0,						 returnType, parameterTypes);				// Create the method.				lock(typeof(AssemblyBuilder))				{					this.privateData = ClrMethodCreate						(((IClrProgramItem)type).ClrHandle, name,						 attributes, helper.sig);				}				// Add the method to the type for post-processing.				type.AddMethod(this);			}	// Add declarative security to this method.	public void AddDeclarativeSecurity(SecurityAction action, 										PermissionSet pset)			{				try				{					type.StartSync();					type.module.assembly.AddDeclarativeSecurity						(this, action, pset);				}				finally				{					type.EndSync();				}			}	// Create the method body from a literal array of IL instructions.	public void CreateMethodBody(byte[] il, int count)			{				try				{					type.StartSync();					if(bodySet)					{						throw new InvalidOperationException							(_("Emit_BodyAlreadySet"));					}					if(il == null)					{						explicitBody = null;					}					else if(count < 0 || count > il.Length)					{						throw new ArgumentOutOfRangeException							("count", _("ArgRange_Array"));					}					else					{						explicitBody = new byte [count];						Array.Copy(il, explicitBody, count);						bodySet = true;					}				}				finally				{					type.EndSync();				}			}	// Define a parameter builder for a particular parameter.	public ParameterBuilder DefineParameter(int position, 											ParameterAttributes attributes, 											String strParamName)			{				try				{					type.StartSync();					if(position <= 0 || position > numParams)					{						throw new ArgumentOutOfRangeException							("position", _("Emit_InvalidParamNum"));					}					return new ParameterBuilder						(type, this, position, attributes, strParamName);				}				finally				{					type.EndSync();				}			}	// Return the base definition for a method.	public override MethodInfo GetBaseDefinition()			{				return this;			}	// Get custom attributes for this method.	public override Object[] GetCustomAttributes(bool inherit)			{				throw new NotSupportedException(_("NotSupp_Builder"));			}	public override Object[] GetCustomAttributes(Type attributeType,												 bool inherit)			{				throw new NotSupportedException(_("NotSupp_Builder"));			}	// Get the IL generator to use for the method body.	public ILGenerator GetILGenerator()			{				return GetILGenerator(64);			}	public ILGenerator GetILGenerator(int size)			{				MethodImplAttributes attrs = GetMethodImplementationFlags();				if((attrs & (MethodImplAttributes.PreserveSig |							 MethodImplAttributes.Unmanaged)) != 0 ||				   (attrs & MethodImplAttributes.CodeTypeMask) !=				   		MethodImplAttributes.IL ||				   (Attributes & MethodAttributes.PinvokeImpl) != 0)				{					throw new InvalidOperationException						(_("Emit_CannotHaveBody"));				}				if(ilGenerator == null)				{					ilGenerator = new ILGenerator(type.module, size);				}				return ilGenerator;			}	// Get the method implementation attributes for this method.	public override MethodImplAttributes GetMethodImplementationFlags()			{				lock(typeof(AssemblyBuilder))				{					return ClrHelpers.GetImplAttrs(privateData);				}			}	// Get the module that owns this method.	public Module GetModule()			{				return type.module;			}	// Get the parameters for this method.	public override ParameterInfo[] GetParameters()			{				lock(typeof(AssemblyBuilder))				{					int param;					ParameterInfo[] parameters = new ParameterInfo [numParams];					for(param = 0; param < numParams; ++param)					{						parameters[param] =							ClrHelpers.GetParameterInfo(this, this, param + 1);					}					return parameters;				}			}	// Get the token code for this method.	public MethodToken GetToken()			{				lock(typeof(AssemblyBuilder))				{					return new MethodToken						(AssemblyBuilder.ClrGetItemToken(privateData));				}			}	// Invoke this method.	public override Object Invoke(Object obj, BindingFlags invokeAttr, 								  Binder binder, Object[] parameters, 								  CultureInfo culture)			{				throw new NotSupportedException(_("NotSupp_Builder"));			}	// Determine if a particular attribute is defined on this method.	public override bool IsDefined(Type attribute_type, bool inherit)			{				throw new NotSupportedException(_("NotSupp_Builder"));			}	// Set an attribute on this method.	public void SetCustomAttribute(CustomAttributeBuilder customBuilder)			{				try				{					type.StartSync();					type.module.assembly.SetCustomAttribute						(this, customBuilder);				}				finally				{					type.EndSync();				}			}	public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)			{				try				{					type.StartSync();					type.module.assembly.SetCustomAttribute						(this, con, binaryAttribute);				}				finally				{					type.EndSync();				}			}	// Set the implementation flags for this method.	public void SetImplementationFlags(MethodImplAttributes attributes)			{				try				{					type.StartSync();					lock(typeof(AssemblyBuilder))					{						ClrMethodSetImplAttrs(privateData, attributes);					}				}				finally				{					type.EndSync();				}			}	// Set the marshalling information for the return type.	public void SetMarshal(UnmanagedMarshal unmanagedMarshal)			{				try				{					type.StartSync();					if(returnBuilder != null)					{						returnBuilder = new ParameterBuilder							(type, this, 0, ParameterAttributes.None, null);					}					returnBuilder.SetMarshal(unmanagedMarshal);				}				finally				{					type.EndSync();				}			}	// Determine if two method builders are equal.	public override bool Equals(Object obj)			{				MethodBuilder mb = (obj as MethodBuilder);				if(mb != null)				{					if(Name != mb.Name)					{						return false;					}					if(Attributes != mb.Attributes)					{						return false;					}					if(ReturnType != mb.ReturnType)					{						return false;					}					ParameterInfo[] params1 = GetParameters();					ParameterInfo[] params2 = mb.GetParameters();					if(params1.Length != params2.Length)					{						return false;					}					int index;					for(index = 0; index < params1.Length; ++index)					{						if(params1[index].Attributes !=						   params2[index].Attributes)						{							return false;						}						if(params1[index].ParameterType !=						   params2[index].ParameterType)						{							return false;						}					}					return true;				}				else				{					return false;				}			}	// Get the hash code for this method.	public override int GetHashCode()			{				return Name.GetHashCode();			}	// Convert this method into a string.	public override String ToString()			{				StringBuilder builder = new StringBuilder();				builder.Append("Name: ");				builder.Append(Name);				builder.Append(Environment.NewLine);				builder.Append("Attributes: ");				builder.Append(Attributes.ToString());				builder.Append(Environment.NewLine);				builder.Append("Method Signature: ");				builder.Append(helper.ToString());				builder.Append(Environment.NewLine);				builder.Append(Environment.NewLine);				return builder.ToString();			}	// Set symbol attribute information for this method.	public void SetSymCustomAttribute(String name, byte[] data)			{				// We don't support symbols at present - ignored.			}	// Get the attributes for this method.	public override MethodAttributes Attributes 			{				get				{					lock(typeof(AssemblyBuilder))					{						return (MethodAttributes)							ClrHelpers.GetMemberAttrs(privateData);					}				}			}	// Get the calling conventions for this method.	public override CallingConventions CallingConvention 			{				get				{					lock(typeof(AssemblyBuilder))					{						return ClrHelpers.GetCallConv(privateData);					}				}			}	// Get the type that declares this method.	public override Type DeclaringType 			{				get				{					return type;				}			}	// Get or set the "initialize locals" flag for this method.	public bool InitLocals 			{				get				{					return initLocals;				}				set				{					initLocals = value;				}			}	// Get the handle for this method.	public override RuntimeMethodHandle MethodHandle			{				get				{					throw new NotSupportedException(_("NotSupp_Builder"));				}			}	// Get the name of this method.	public override String Name 			{				get				{					lock(typeof(AssemblyBuilder))					{						return ClrHelpers.GetName(this);					}				}			}	// Get the reflected type that contains this method.	public override Type ReflectedType 			{				get				{					return type;				}			}	// Get the return type for this method.	public override Type ReturnType 			{				get				{					return returnType;				}			}	// Get the string form of the signature of this method.	public String Signature 			{				get				{					return helper.ToString();				}			}	// Get the custom attribute information for the return type.	public override ICustomAttributeProvider ReturnTypeCustomAttributes			{				get				{					// Nothing to do here.					return null;				}			}	// Get the CLR handle for this method.	IntPtr IClrProgramItem.ClrHandle			{				get				{					return privateData;				}			}	// Finalize this method by writing its code to the output image.	internal void FinalizeMethod()			{				int rva;				if(bodySet)				{					if(explicitBody == null)					{						rva = 0;					}					else					{						rva = ILGenerator.WriteExplicitCode							(type.module, explicitBody, initLocals);					}				}				else if(ilGenerator != null)				{					rva = ilGenerator.WriteCode(initLocals);				}				else				{					rva = 0;				}				lock(typeof(AssemblyBuilder))				{					ClrMethodSetRVA(privateData, rva);				}			}	// Detach this item.	void IDetachItem.Detach()			{				privateData = IntPtr.Zero;			}	// Create a new method and attach it to a particular class.	[MethodImpl(MethodImplOptions.InternalCall)]	extern internal static IntPtr ClrMethodCreate			(IntPtr classInfo, String name,			 MethodAttributes attributes, IntPtr signature);	// Set the implementation attributes for a method item.	[MethodImpl(MethodImplOptions.InternalCall)]	extern internal static void ClrMethodSetImplAttrs			(IntPtr item, MethodImplAttributes attributes);	// Create a member reference for a vararg method call.	[MethodImpl(MethodImplOptions.InternalCall)]	extern internal static int ClrMethodCreateVarArgRef			(IntPtr module, int methodToken, IntPtr signature);	// Set the RVA for a method's code.	[MethodImpl(MethodImplOptions.InternalCall)]	extern internal static void ClrMethodSetRVA(IntPtr method, int rva);	// Add a PInvoke declaration to a method.	[MethodImpl(MethodImplOptions.InternalCall)]	extern internal static void ClrMethodAddPInvoke			(IntPtr method, int pinvAttrs, String dllName, String entryName);}; // class MethodBuilder#endif // CONFIG_REFLECTION_EMIT}; // namespace System.Reflection.Emit

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?