signaturehelper.cs

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

CS
505
字号
/* * SignatureHelper.cs - Implementation of the *		"System.Reflection.Emit.SignatureHelper" 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.Text;using System.Reflection;using System.Globalization;using System.Runtime.InteropServices;using System.Runtime.CompilerServices;public sealed class SignatureHelper : IDetachItem{	// Internal state.	private Module mod;	private IntPtr context;	internal IntPtr sig;	internal int numArgs;	private CallingConvention callConv;	private bool field;	private long bytesOffset;	// Constructor.	private SignatureHelper(Module mod, IntPtr context)			{				this.mod = mod;				this.context = context;				this.sig = IntPtr.Zero;				this.numArgs = 0;				this.callConv = (CallingConvention)0;				this.field = true;				this.bytesOffset = -1;				((ModuleBuilder)mod).assembly.AddDetach(this);			}	private SignatureHelper(Module mod, IntPtr context, IntPtr sig)			{				this.mod = mod;				this.context = context;				this.sig = sig;				this.numArgs = 0;				this.callConv = (CallingConvention)0;				this.field = false;				this.bytesOffset = -1;				((ModuleBuilder)mod).assembly.AddDetach(this);			}	private SignatureHelper(Module mod, IntPtr context, IntPtr sig,							CallingConvention callConv)			{				this.mod = mod;				this.context = context;				this.sig = sig;				this.numArgs = 0;				this.callConv = callConv;				this.field = false;				this.bytesOffset = -1;				((ModuleBuilder)mod).assembly.AddDetach(this);			}	// Convert a module into an ILContext value.	private static IntPtr ModuleToContext(Module mod)			{				if(mod == null)				{					throw new ArgumentNullException("mod");				}				else if(!(mod is ModuleBuilder))				{					throw new NotSupportedException						(_("Emit_NeedDynamicModule"));				}				return ClrSigModuleToContext(mod.privateData);			}	// Convert a C# type into an ILType value.	private static IntPtr CSToILType(Module mod, IntPtr context, Type type)			{				if(type == null)				{					return ClrSigCreatePrimitive(context, typeof(void));				}				else if(type.IsPrimitive || type == typeof(void))				{					return ClrSigCreatePrimitive(context, type);				}				else if(type.IsArray)				{					return ClrSigCreateArray						(context, type.GetArrayRank(),						 CSToILType(mod, context, type.GetElementType()));				}				else if(type.IsPointer)				{					return ClrSigCreatePointer						(context,						 CSToILType(mod, context, type.GetElementType()));				}				else if(type.IsByRef)				{					return ClrSigCreateByRef						(context,						 CSToILType(mod, context, type.GetElementType()));				}				else if(type.HasGenericArguments ||						type.HasGenericParameters)				{					throw new NotSupportedException						(_("Emit_GenericsNotSupported"));				}				else if(type.IsValueType)				{					return ClrSigCreateValueType						(mod.privateData,						 (((ModuleBuilder)mod).GetTypeToken(type)).Token);				}				else				{					return ClrSigCreateClass						(mod.privateData,						 (((ModuleBuilder)mod).GetTypeToken(type)).Token);				}			}	internal static IntPtr CSToILType(Module mod, Type type)			{				lock(typeof(AssemblyBuilder))				{					return CSToILType(mod, ModuleToContext(mod), type);				}			}	// Create a signature helper for a field signature.	public static SignatureHelper GetFieldSigHelper(Module mod)			{				lock(typeof(AssemblyBuilder))				{					IntPtr context = ModuleToContext(mod);					return new SignatureHelper(mod, context);				}			}	// Create a signature helper for a local variable signature.	public static SignatureHelper GetLocalVarSigHelper(Module mod)			{				lock(typeof(AssemblyBuilder))				{					IntPtr context = ModuleToContext(mod);					return new SignatureHelper						(mod, context, ClrSigCreateLocal(context));				}			}	// Create a signature helper for a method signature.	internal static SignatureHelper GetMethodSigHelper				(Module mod, CallingConventions callConv,				 CallingConvention unmanagedCallConv, Type returnType,				 Type[] parameterTypes)			{				lock(typeof(AssemblyBuilder))				{					// Convert the module into a signature create context.					IntPtr context = ModuleToContext(mod);					// Determine the calling convention flags to use.					int conv = 0;		/* default */					if((callConv & CallingConventions.VarArgs) != 0)					{						conv = 0x05;	/* vararg */					}					if((callConv & CallingConventions.HasThis) != 0)					{						conv |= 0x20;	/* hasthis */					}					if((callConv & CallingConventions.ExplicitThis) != 0)					{						conv |= 0x40;	/* explicitthis */					}					// Create the basic signature helper.					IntPtr sig = ClrSigCreateMethod						(context, conv, CSToILType(mod, context, returnType));					SignatureHelper helper = new SignatureHelper						(mod, context, sig, unmanagedCallConv);					// Add the parameters to the helper.					if(parameterTypes != null)					{						foreach(Type type in parameterTypes)						{							helper.AddArgument(type);						}					}					return helper;				}			}	public static SignatureHelper GetMethodSigHelper				(Module mod, CallingConvention unmanagedCallConv,				 Type returnType)			{				return GetMethodSigHelper					(mod, CallingConventions.Standard,					 unmanagedCallConv, returnType, null);			}	public static SignatureHelper GetMethodSigHelper				(Module mod, CallingConventions callingConvention,				 Type returnType)			{				return GetMethodSigHelper					(mod, callingConvention, (CallingConvention)0,					 returnType, null);			}	public static SignatureHelper GetMethodSigHelper				(Module mod, Type returnType, Type[] parameterTypes)			{				return GetMethodSigHelper					(mod, CallingConventions.Standard,					 (CallingConvention)0, returnType, parameterTypes);			}	internal static SignatureHelper GetMethodSigHelper				(Module mod, MethodToken token)			{				lock(typeof(AssemblyBuilder))				{					IntPtr context = ModuleToContext(mod);					IntPtr sig = ClrSigCreateMethodCopy						(context, mod.privateData, token.Token);					return new SignatureHelper(mod, context, sig);				}			}	// Create a signature helper for a property signature.	public static SignatureHelper GetPropertySigHelper				(Module mod, Type returnType, Type[] parameterTypes)			{				lock(typeof(AssemblyBuilder))				{					// Convert the module into a signature create context.					IntPtr context = ModuleToContext(mod);					// Create the basic signature helper.					IntPtr sig = ClrSigCreateProperty						(context, CSToILType(mod, context, returnType));					SignatureHelper helper = new SignatureHelper						(mod, context, sig);					// Add the parameters to the helper.					if(parameterTypes != null)					{						foreach(Type type in parameterTypes)						{							helper.AddArgument(type);						}					}					return helper;				}			}	// Add an argument type to a signature.	public void AddArgument(Type clsArgument)			{				lock(typeof(AssemblyBuilder))				{					if (bytesOffset != -1)					{						throw new ArgumentException(/* TODO */);					}					if(clsArgument == null)					{						throw new ArgumentNullException("clsArgument");					}					IntPtr type = CSToILType(mod, context, clsArgument);					if (field && sig == IntPtr.Zero)					{						sig = type;					}					else if (field)					{						throw new InvalidOperationException							(_("Emit_InvalidSigArgument"));					}					else if(!ClrSigAddArgument(context, sig, type))					{						throw new InvalidOperationException							(_("Emit_InvalidSigArgument"));					}					++numArgs;				}			}	// Add a vararg sentinel to a signature.	public void AddSentinel()			{				lock(typeof(AssemblyBuilder))				{					if (bytesOffset != -1)					{						throw new ArgumentException(/* TODO */);					}					if (field)					{						throw new InvalidOperationException							(_("Emit_InvalidSigArgument"));					}					if(!ClrSigAddSentinel(context, sig))					{						throw new InvalidOperationException							(_("Emit_InvalidSigArgument"));					}				}			}	// Determine if two signatures are equal.	public override bool Equals(Object obj)			{				lock(typeof(AssemblyBuilder))				{					SignatureHelper helper = (obj as SignatureHelper);					if(helper != null &&					   helper.mod == mod &&					   helper.field == field)					{						return ClrSigIdentical(sig, helper.sig);					}					else					{						return false;					}				}			}	// Get the hash code for a signature.	public override int GetHashCode()			{				lock(typeof(AssemblyBuilder))				{					return ClrSigGetHashCode(sig);				}			}	// Convert the signature into an array of bytes.	public byte[] GetSignature()			{				lock(typeof(AssemblyBuilder))				{					if (bytesOffset == -1)					{						bytesOffset = ClrSigFinalize							(mod.privateData, sig, field);					}					return ClrSigGetBytes						(mod.privateData, bytesOffset);				}			}	// Get a token for a stand alone signature made from this signature.	internal int StandAloneToken()			{				if (sig == IntPtr.Zero)				{					return 0;				}				return ClrStandAloneToken(mod.privateData, sig);			}	// Convert this signature into a string.	public override String ToString()			{				byte[] bytes = GetSignature();				StringBuilder builder = new StringBuilder();				builder.Append("Length: " + bytes.Length.ToString() +							   Environment.NewLine);				if(bytes[0] == 0x06)	/* field */				{					builder.Append("Field Signature" + Environment.NewLine);				}				else				{					builder.Append("Arguments: " + numArgs.ToString() +								   Environment.NewLine);				}				builder.Append("Signature:" + Environment.NewLine);				foreach(byte val in bytes)				{					builder.Append(val.ToString() + " ");				}				builder.Append(Environment.NewLine);				return builder.ToString();			}	// Detach this item.	void IDetachItem.Detach()			{				context = IntPtr.Zero;				sig = IntPtr.Zero;			}	// Internal version of "ModuleToContext".	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static IntPtr ClrSigModuleToContext(IntPtr module);	// Create a primitive type value.	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static IntPtr ClrSigCreatePrimitive			(IntPtr context, Type type);	// Create an array type value.	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static IntPtr ClrSigCreateArray			(IntPtr context, int rank, IntPtr elemType);	// Create a pointer type value.	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static IntPtr ClrSigCreatePointer			(IntPtr context, IntPtr elemType);	// Create a by-reference type value.	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static IntPtr ClrSigCreateByRef			(IntPtr context, IntPtr elemType);	// Create a value type value.	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static IntPtr ClrSigCreateValueType			(IntPtr module, int typeToken);	// Create a class type value.	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static IntPtr ClrSigCreateClass			(IntPtr module, int typeToken);	// Create a local variable signature type value.	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static IntPtr ClrSigCreateLocal(IntPtr context);	// Create a method signature type value.	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static IntPtr ClrSigCreateMethod			(IntPtr context, int callConv, IntPtr returnType);	// Create a method signature type value as a copy of another.	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static IntPtr ClrSigCreateMethodCopy			(IntPtr context, IntPtr module, int methodToken);	// Create a property signature type value.	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static IntPtr ClrSigCreateProperty			(IntPtr context, IntPtr returnType);	// Add an argument to a signature.  Returns false if args not allowed.	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static bool ClrSigAddArgument			(IntPtr context, IntPtr sig, IntPtr arg);	// Add a sentinel to a signature.  Returns false if args not allowed.	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static bool ClrSigAddSentinel(IntPtr context, IntPtr sig);	// Determine if two signatures are identical.	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static bool ClrSigIdentical(IntPtr sig1, IntPtr sig2);	// Get the hash code for a signature.	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static int ClrSigGetHashCode(IntPtr sig);	// Write the signature to the blob and get its offset.	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static long ClrSigFinalize			(IntPtr module, IntPtr sig, bool field);	// Get the bytes of a signature from the blob.	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static byte[] ClrSigGetBytes(IntPtr module, long offset);	// Create an ILStandAloneSig from the signature and return its token.	[MethodImpl(MethodImplOptions.InternalCall)]	extern private static int ClrStandAloneToken(IntPtr module, IntPtr sig);}; // class SignatureHelper#endif // CONFIG_REFLECTION_EMIT}; // namespace System.Reflection.Emit

⌨️ 快捷键说明

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