Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Reflection / Emit / MethodBuilder.cs / 1305376 / MethodBuilder.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// [....]
//
namespace System.Reflection.Emit
{
using System.Text;
using System;
using CultureInfo = System.Globalization.CultureInfo;
using System.Diagnostics.SymbolStore;
using System.Reflection;
using System.Security;
using System.Collections;
using System.Collections.Generic;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Diagnostics.Contracts;
[HostProtection(MayLeakOnAbort = true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_MethodBuilder))]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class MethodBuilder : MethodInfo, _MethodBuilder
{
#region Private Data Members
// Identity
internal String m_strName; // The name of the method
private MethodToken m_tkMethod; // The token of this method
private ModuleBuilder m_module;
internal TypeBuilder m_containingType;
// IL
private int[] m_RVAFixups; // The location of all RVA fixups. Primarily used for Strings.
private int[] m_mdMethodFixups; // The location of all of the token fixups.
private SignatureHelper m_localSignature;
internal LocalSymInfo m_localSymInfo; // keep track debugging local information
internal ILGenerator m_ilGenerator;
private byte[] m_ubBody; // The IL for the method
private int m_numExceptions; // The number of exceptions. Each try-catch tuple is a separate exception.
private __ExceptionInstance[] m_exceptions; //The instance of each exception.
// Flags
internal bool m_bIsBaked;
private bool m_bIsGlobalMethod;
private bool m_fInitLocals; // indicating if the method stack frame will be zero initialized or not.
// Attributes
private MethodAttributes m_iAttributes;
private CallingConventions m_callingConvention;
private MethodImplAttributes m_dwMethodImplFlags;
// Parameters
private SignatureHelper m_signature;
internal Type[] m_parameterTypes;
private ParameterBuilder m_retParam;
private Type m_returnType;
private Type[] m_returnTypeRequiredCustomModifiers;
private Type[] m_returnTypeOptionalCustomModifiers;
private Type[][] m_parameterTypeRequiredCustomModifiers;
private Type[][] m_parameterTypeOptionalCustomModifiers;
// Generics
private GenericTypeParameterBuilder[] m_inst;
private bool m_bIsGenMethDef;
#endregion
#region Constructor
internal MethodBuilder(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] parameterTypes, ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod)
{
Init(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null, mod, type, bIsGlobalMethod);
}
internal MethodBuilder(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers,
ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod)
{
Init(name, attributes, callingConvention,
returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers,
mod, type, bIsGlobalMethod);
}
private void Init(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers,
ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod)
{
if (name == null)
throw new ArgumentNullException("name");
if (name.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
if (name[0] == '\0')
throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), "name");
if (mod == null)
throw new ArgumentNullException("mod");
Contract.EndContractBlock();
if (parameterTypes != null)
{
foreach(Type t in parameterTypes)
{
if (t == null)
throw new ArgumentNullException("parameterTypes");
}
}
m_strName = name;
m_module = mod;
m_containingType = type;
m_localSignature = SignatureHelper.GetLocalVarSigHelper(mod);
//
//if (returnType == null)
//{
// m_returnType = typeof(void);
//}
//else
{
m_returnType = returnType;
}
if ((attributes & MethodAttributes.Static) == 0)
{
// turn on the has this calling convention
callingConvention = callingConvention | CallingConventions.HasThis;
}
else if ((attributes & MethodAttributes.Virtual) != 0)
{
// A method can't be both static and virtual
throw new ArgumentException(Environment.GetResourceString("Arg_NoStaticVirtual"));
}
if ((attributes & MethodAttributes.SpecialName) != MethodAttributes.SpecialName)
{
if ((type.Attributes & TypeAttributes.Interface) == TypeAttributes.Interface)
{
// methods on interface have to be abstract + virtual except special name methods such as type initializer
if ((attributes & (MethodAttributes.Abstract | MethodAttributes.Virtual)) !=
(MethodAttributes.Abstract | MethodAttributes.Virtual) &&
(attributes & MethodAttributes.Static) == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_BadAttributeOnInterfaceMethod"));
}
}
m_callingConvention = callingConvention;
if (parameterTypes != null)
{
m_parameterTypes = new Type[parameterTypes.Length];
Array.Copy(parameterTypes, m_parameterTypes, parameterTypes.Length);
}
else
{
m_parameterTypes = null;
}
m_returnTypeRequiredCustomModifiers = returnTypeRequiredCustomModifiers;
m_returnTypeOptionalCustomModifiers = returnTypeOptionalCustomModifiers;
m_parameterTypeRequiredCustomModifiers = parameterTypeRequiredCustomModifiers;
m_parameterTypeOptionalCustomModifiers = parameterTypeOptionalCustomModifiers;
// m_signature = SignatureHelper.GetMethodSigHelper(mod, callingConvention,
// returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
// parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
m_iAttributes = attributes;
m_bIsGlobalMethod = bIsGlobalMethod;
m_bIsBaked = false;
m_fInitLocals = true;
m_localSymInfo = new LocalSymInfo();
m_ubBody = null;
m_ilGenerator = null;
// Default is managed IL. Manged IL has bit flag 0x0020 set off
m_dwMethodImplFlags = MethodImplAttributes.IL;
}
#endregion
#region Internal Members
internal void CheckContext(params Type[][] typess)
{
m_module.CheckContext(typess);
}
internal void CheckContext(params Type[] types)
{
m_module.CheckContext(types);
}
[System.Security.SecurityCritical] // auto-generated
internal void CreateMethodBodyHelper(ILGenerator il)
{
// Sets the IL of the method. An ILGenerator is passed as an argument and the method
// queries this instance to get all of the information which it needs.
if (il == null)
{
throw new ArgumentNullException("il");
}
Contract.EndContractBlock();
__ExceptionInfo[] excp;
int counter=0;
int[] filterAddrs;
int[] catchAddrs;
int[] catchEndAddrs;
Type[] catchClass;
int[] type;
int numCatch;
int start, end;
ModuleBuilder dynMod = (ModuleBuilder) m_module;
m_containingType.ThrowIfCreated();
if (m_bIsBaked)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodHasBody"));
}
if (il.m_methodBuilder != this && il.m_methodBuilder != null)
{
// you don't need to call CreateMethodBody when you get your ILGenerator
// through MethodBuilder::GetILGenerator.
//
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadILGeneratorUsage"));
}
ThrowIfShouldNotHaveBody();
if (il.m_ScopeTree.m_iOpenScopeCount != 0)
{
// There are still unclosed local scope
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_OpenLocalVariableScope"));
}
m_ubBody = il.BakeByteArray();
m_RVAFixups = il.GetRVAFixups();
m_mdMethodFixups = il.GetTokenFixups();
//Okay, now the fun part. Calculate all of the exceptions.
excp = il.GetExceptions();
m_numExceptions = CalculateNumberOfExceptions(excp);
if (m_numExceptions>0)
{
m_exceptions = new __ExceptionInstance[m_numExceptions];
for (int i=0; i 0 && (m_parameterTypes == null || position > m_parameterTypes.Length))
throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_ParamSequence"));
attributes = attributes & ~ParameterAttributes.ReservedMask;
return new ParameterBuilder(this, position, attributes, strParamName);
}
[System.Security.SecuritySafeCritical] // auto-generated
[Obsolete("An alternate API is available: Emit the MarshalAs custom attribute instead. http://go.microsoft.com/fwlink/?linkid=14202")]
public void SetMarshal(UnmanagedMarshal unmanagedMarshal)
{
ThrowIfGeneric ();
// set Marshal info for the return type
m_containingType.ThrowIfCreated();
if (m_retParam == null)
{
m_retParam = new ParameterBuilder(this, 0, 0, null);
}
m_retParam.SetMarshal(unmanagedMarshal);
}
private List m_symCustomAttrs;
private struct SymCustomAttr
{
public SymCustomAttr(String name, byte[] data)
{
m_name = name;
m_data = data;
}
public String m_name;
public byte[] m_data;
}
public void SetSymCustomAttribute(String name, byte[] data)
{
// Note that this API is rarely used. Support for custom attributes in PDB files was added in
// Whidbey and as of 8/2007 the only known user is the C# compiler. There seems to be little
// value to this for Reflection.Emit users since they can always use metadata custom attributes.
// Some versions of the symbol writer used in the CLR will ignore these entirely. This API has
// been removed from the Silverlight API surface area, but we should also consider removing it
// from future desktop product versions as well.
ThrowIfGeneric ();
// This is different from CustomAttribute. This is stored into the SymWriter.
m_containingType.ThrowIfCreated();
ModuleBuilder dynMod = (ModuleBuilder) m_module;
if ( dynMod.GetSymWriter() == null)
{
// Cannot SetSymCustomAttribute when it is not a debug module
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule"));
}
if (m_symCustomAttrs == null)
m_symCustomAttrs = new List();
m_symCustomAttrs.Add(new SymCustomAttr(name, data));
}
#if FEATURE_CAS_POLICY
[System.Security.SecuritySafeCritical] // auto-generated
public void AddDeclarativeSecurity(SecurityAction action, PermissionSet pset)
{
if (pset == null)
throw new ArgumentNullException("pset");
Contract.EndContractBlock();
ThrowIfGeneric ();
#pragma warning disable 618
if (!Enum.IsDefined(typeof(SecurityAction), action) ||
action == SecurityAction.RequestMinimum ||
action == SecurityAction.RequestOptional ||
action == SecurityAction.RequestRefuse)
{
throw new ArgumentOutOfRangeException("action");
}
#pragma warning restore 618
// cannot declarative security after type is created
m_containingType.ThrowIfCreated();
// Translate permission set into serialized format (uses standard binary serialization format).
byte[] blob = null;
int length = 0;
if (!pset.IsEmpty())
{
blob = pset.EncodeXml();
length = blob.Length;
}
// Write the blob into the metadata.
TypeBuilder.AddDeclarativeSecurity(m_module.GetNativeHandle(), MetadataTokenInternal, action, blob, length);
}
#endif // FEATURE_CAS_POLICY
public void CreateMethodBody(byte[] il,int count)
{
ThrowIfGeneric();
// Note that when user calls this function, there are a few information that client is
// not able to supply: local signature, exception handlers, max stack size, a list of Token fixup, a list of RVA fixup
if (m_bIsBaked)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodBaked"));
}
m_containingType.ThrowIfCreated();
if (il != null && (count < 0 || count > il.Length))
throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (il == null) {
m_ubBody = null;
return;
}
m_ubBody = new byte[count];
Array.Copy(il,m_ubBody,count);
m_bIsBaked=true;
}
[System.Security.SecuritySafeCritical] // auto-generated
public void SetImplementationFlags(MethodImplAttributes attributes)
{
ThrowIfGeneric ();
m_containingType.ThrowIfCreated ();
m_dwMethodImplFlags = attributes;
m_canBeRuntimeImpl = true;
TypeBuilder.SetMethodImpl(m_module.GetNativeHandle(), MetadataTokenInternal, attributes);
}
public ILGenerator GetILGenerator() {
ThrowIfGeneric ();
ThrowIfShouldNotHaveBody();
if (m_ilGenerator == null)
m_ilGenerator = new ILGenerator(this);
return m_ilGenerator;
}
public ILGenerator GetILGenerator(int size) {
ThrowIfGeneric ();
ThrowIfShouldNotHaveBody();
if (m_ilGenerator == null)
m_ilGenerator = new ILGenerator(this, size);
return m_ilGenerator;
}
private void ThrowIfShouldNotHaveBody() {
if ((m_dwMethodImplFlags&MethodImplAttributes.CodeTypeMask) != MethodImplAttributes.IL ||
(m_dwMethodImplFlags & MethodImplAttributes.Unmanaged) != 0 ||
(m_iAttributes & MethodAttributes.PinvokeImpl) != 0 ||
m_isDllImport)
{
// cannot attach method body if methodimpl is marked not marked as managed IL
//
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ShouldNotHaveMethodBody"));
}
}
public bool InitLocals
{
// Property is set to true if user wishes to have zero initialized stack frame for this method. Default to false.
get { ThrowIfGeneric (); return m_fInitLocals; }
set { ThrowIfGeneric (); m_fInitLocals = value; }
}
public Module GetModule()
{
return GetModuleBuilder();
}
public String Signature
{
[System.Security.SecuritySafeCritical] // auto-generated
get
{
return GetMethodSignature().ToString();
}
}
[System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
if (con == null)
throw new ArgumentNullException("con");
if (binaryAttribute == null)
throw new ArgumentNullException("binaryAttribute");
Contract.EndContractBlock();
ThrowIfGeneric();
TypeBuilder.DefineCustomAttribute(m_module, MetadataTokenInternal,
((ModuleBuilder)m_module).GetConstructorToken(con).Token,
binaryAttribute,
false, false);
if (IsKnownCA(con))
ParseCA(con, binaryAttribute);
}
[System.Security.SecuritySafeCritical] // auto-generated
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
{
if (customBuilder == null)
throw new ArgumentNullException("customBuilder");
Contract.EndContractBlock();
ThrowIfGeneric();
customBuilder.CreateCustomAttribute((ModuleBuilder)m_module, MetadataTokenInternal);
if (IsKnownCA(customBuilder.m_con))
ParseCA(customBuilder.m_con, customBuilder.m_blob);
}
// this method should return true for any and every ca that requires more work
// than just setting the ca
private bool IsKnownCA(ConstructorInfo con)
{
Type caType = con.DeclaringType;
if (caType == typeof(System.Runtime.CompilerServices.MethodImplAttribute)) return true;
else if (caType == typeof(DllImportAttribute)) return true;
else return false;
}
private void ParseCA(ConstructorInfo con, byte[] blob)
{
Type caType = con.DeclaringType;
if (caType == typeof(System.Runtime.CompilerServices.MethodImplAttribute))
{
// dig through the blob looking for the MethodImplAttributes flag
// that must be in the MethodCodeType field
// for now we simply set a flag that relaxes the check when saving and
// allows this method to have no body when any kind of MethodImplAttribute is present
m_canBeRuntimeImpl = true;
}
else if (caType == typeof(DllImportAttribute)) {
m_canBeRuntimeImpl = true;
m_isDllImport = true;
}
}
internal bool m_canBeRuntimeImpl = false;
internal bool m_isDllImport = false;
#endregion
void _MethodBuilder.GetTypeInfoCount(out uint pcTInfo)
{
throw new NotImplementedException();
}
void _MethodBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
{
throw new NotImplementedException();
}
void _MethodBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
{
throw new NotImplementedException();
}
void _MethodBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
{
throw new NotImplementedException();
}
}
internal class LocalSymInfo
{
// This class tracks the local variable's debugging information
// and namespace information with a given active lexical scope.
#region Internal Data Members
internal String[] m_strName;
internal byte[][] m_ubSignature;
internal int[] m_iLocalSlot;
internal int[] m_iStartOffset;
internal int[] m_iEndOffset;
internal int m_iLocalSymCount; // how many entries in the arrays are occupied
internal String[] m_namespace;
internal int m_iNameSpaceCount;
internal const int InitialSize = 16;
#endregion
#region Constructor
internal LocalSymInfo()
{
// initialize data variables
m_iLocalSymCount = 0;
m_iNameSpaceCount = 0;
}
#endregion
#region Private Members
private void EnsureCapacityNamespace()
{
if (m_iNameSpaceCount == 0)
{
m_namespace = new String[InitialSize];
}
else if (m_iNameSpaceCount == m_namespace.Length)
{
String [] strTemp = new String [checked(m_iNameSpaceCount * 2)];
Array.Copy(m_namespace, strTemp, m_iNameSpaceCount);
m_namespace = strTemp;
}
}
private void EnsureCapacity()
{
if (m_iLocalSymCount == 0)
{
// First time. Allocate the arrays.
m_strName = new String[InitialSize];
m_ubSignature = new byte[InitialSize][];
m_iLocalSlot = new int[InitialSize];
m_iStartOffset = new int[InitialSize];
m_iEndOffset = new int[InitialSize];
}
else if (m_iLocalSymCount == m_strName.Length)
{
// the arrays are full. Enlarge the arrays
// why aren't we just using lists here?
int newSize = checked(m_iLocalSymCount * 2);
int[] temp = new int [newSize];
Array.Copy(m_iLocalSlot, temp, m_iLocalSymCount);
m_iLocalSlot = temp;
temp = new int [newSize];
Array.Copy(m_iStartOffset, temp, m_iLocalSymCount);
m_iStartOffset = temp;
temp = new int [newSize];
Array.Copy(m_iEndOffset, temp, m_iLocalSymCount);
m_iEndOffset = temp;
String [] strTemp = new String [newSize];
Array.Copy(m_strName, strTemp, m_iLocalSymCount);
m_strName = strTemp;
byte[][] ubTemp = new byte[newSize][];
Array.Copy(m_ubSignature, ubTemp, m_iLocalSymCount);
m_ubSignature = ubTemp;
}
}
#endregion
#region Internal Members
internal void AddLocalSymInfo(String strName,byte[] signature,int slot,int startOffset,int endOffset)
{
// make sure that arrays are large enough to hold addition info
EnsureCapacity();
m_iStartOffset[m_iLocalSymCount] = startOffset;
m_iEndOffset[m_iLocalSymCount] = endOffset;
m_iLocalSlot[m_iLocalSymCount] = slot;
m_strName[m_iLocalSymCount] = strName;
m_ubSignature[m_iLocalSymCount] = signature;
checked {m_iLocalSymCount++; }
}
internal void AddUsingNamespace(String strNamespace)
{
EnsureCapacityNamespace();
m_namespace[m_iNameSpaceCount] = strNamespace;
checked { m_iNameSpaceCount++; }
}
internal virtual void EmitLocalSymInfo(ISymbolWriter symWriter)
{
int i;
for (i = 0; i < m_iLocalSymCount; i ++)
{
symWriter.DefineLocalVariable(
m_strName[i],
FieldAttributes.PrivateScope,
m_ubSignature[i],
SymAddressKind.ILOffset,
m_iLocalSlot[i],
0, // addr2 is not used yet
0, // addr3 is not used
m_iStartOffset[i],
m_iEndOffset[i]);
}
for (i = 0; i < m_iNameSpaceCount; i ++)
{
symWriter.UsingNamespace(m_namespace[i]);
}
}
#endregion
}
internal struct __ExceptionInstance
{
#region Internal Members
// Keep in [....] with unmanged structure.
internal int m_exceptionClass;
internal int m_startAddress;
internal int m_endAddress;
internal int m_filterAddress;
internal int m_handleAddress;
internal int m_handleEndAddress;
internal int m_type;
#endregion
#region Constructor
internal __ExceptionInstance(int start,int end,int filterAddr,int handle,int handleEnd,int type,int exceptionClass)
{
m_startAddress=start;
m_endAddress=end;
m_filterAddress = filterAddr;
m_handleAddress=handle;
m_handleEndAddress=handleEnd;
m_type=type;
m_exceptionClass = exceptionClass;
}
#endregion
#region Object Overrides
public override bool Equals(Object obj)
{
if (obj!=null && (obj is __ExceptionInstance)) {
__ExceptionInstance that = (__ExceptionInstance) obj;
return that.m_exceptionClass == m_exceptionClass &&
that.m_startAddress == m_startAddress && that.m_endAddress == m_endAddress &&
that.m_filterAddress == m_filterAddress &&
that.m_handleAddress == m_handleAddress && that.m_handleEndAddress == m_handleEndAddress;
}
else
return false;
}
public override int GetHashCode()
{
return m_exceptionClass ^ m_startAddress ^ m_endAddress ^ m_filterAddress ^ m_handleAddress ^ m_handleEndAddress ^ m_type;
}
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// [....]
//
namespace System.Reflection.Emit
{
using System.Text;
using System;
using CultureInfo = System.Globalization.CultureInfo;
using System.Diagnostics.SymbolStore;
using System.Reflection;
using System.Security;
using System.Collections;
using System.Collections.Generic;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Diagnostics.Contracts;
[HostProtection(MayLeakOnAbort = true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_MethodBuilder))]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class MethodBuilder : MethodInfo, _MethodBuilder
{
#region Private Data Members
// Identity
internal String m_strName; // The name of the method
private MethodToken m_tkMethod; // The token of this method
private ModuleBuilder m_module;
internal TypeBuilder m_containingType;
// IL
private int[] m_RVAFixups; // The location of all RVA fixups. Primarily used for Strings.
private int[] m_mdMethodFixups; // The location of all of the token fixups.
private SignatureHelper m_localSignature;
internal LocalSymInfo m_localSymInfo; // keep track debugging local information
internal ILGenerator m_ilGenerator;
private byte[] m_ubBody; // The IL for the method
private int m_numExceptions; // The number of exceptions. Each try-catch tuple is a separate exception.
private __ExceptionInstance[] m_exceptions; //The instance of each exception.
// Flags
internal bool m_bIsBaked;
private bool m_bIsGlobalMethod;
private bool m_fInitLocals; // indicating if the method stack frame will be zero initialized or not.
// Attributes
private MethodAttributes m_iAttributes;
private CallingConventions m_callingConvention;
private MethodImplAttributes m_dwMethodImplFlags;
// Parameters
private SignatureHelper m_signature;
internal Type[] m_parameterTypes;
private ParameterBuilder m_retParam;
private Type m_returnType;
private Type[] m_returnTypeRequiredCustomModifiers;
private Type[] m_returnTypeOptionalCustomModifiers;
private Type[][] m_parameterTypeRequiredCustomModifiers;
private Type[][] m_parameterTypeOptionalCustomModifiers;
// Generics
private GenericTypeParameterBuilder[] m_inst;
private bool m_bIsGenMethDef;
#endregion
#region Constructor
internal MethodBuilder(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] parameterTypes, ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod)
{
Init(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null, mod, type, bIsGlobalMethod);
}
internal MethodBuilder(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers,
ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod)
{
Init(name, attributes, callingConvention,
returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers,
mod, type, bIsGlobalMethod);
}
private void Init(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers,
ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod)
{
if (name == null)
throw new ArgumentNullException("name");
if (name.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
if (name[0] == '\0')
throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), "name");
if (mod == null)
throw new ArgumentNullException("mod");
Contract.EndContractBlock();
if (parameterTypes != null)
{
foreach(Type t in parameterTypes)
{
if (t == null)
throw new ArgumentNullException("parameterTypes");
}
}
m_strName = name;
m_module = mod;
m_containingType = type;
m_localSignature = SignatureHelper.GetLocalVarSigHelper(mod);
//
//if (returnType == null)
//{
// m_returnType = typeof(void);
//}
//else
{
m_returnType = returnType;
}
if ((attributes & MethodAttributes.Static) == 0)
{
// turn on the has this calling convention
callingConvention = callingConvention | CallingConventions.HasThis;
}
else if ((attributes & MethodAttributes.Virtual) != 0)
{
// A method can't be both static and virtual
throw new ArgumentException(Environment.GetResourceString("Arg_NoStaticVirtual"));
}
if ((attributes & MethodAttributes.SpecialName) != MethodAttributes.SpecialName)
{
if ((type.Attributes & TypeAttributes.Interface) == TypeAttributes.Interface)
{
// methods on interface have to be abstract + virtual except special name methods such as type initializer
if ((attributes & (MethodAttributes.Abstract | MethodAttributes.Virtual)) !=
(MethodAttributes.Abstract | MethodAttributes.Virtual) &&
(attributes & MethodAttributes.Static) == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_BadAttributeOnInterfaceMethod"));
}
}
m_callingConvention = callingConvention;
if (parameterTypes != null)
{
m_parameterTypes = new Type[parameterTypes.Length];
Array.Copy(parameterTypes, m_parameterTypes, parameterTypes.Length);
}
else
{
m_parameterTypes = null;
}
m_returnTypeRequiredCustomModifiers = returnTypeRequiredCustomModifiers;
m_returnTypeOptionalCustomModifiers = returnTypeOptionalCustomModifiers;
m_parameterTypeRequiredCustomModifiers = parameterTypeRequiredCustomModifiers;
m_parameterTypeOptionalCustomModifiers = parameterTypeOptionalCustomModifiers;
// m_signature = SignatureHelper.GetMethodSigHelper(mod, callingConvention,
// returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
// parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
m_iAttributes = attributes;
m_bIsGlobalMethod = bIsGlobalMethod;
m_bIsBaked = false;
m_fInitLocals = true;
m_localSymInfo = new LocalSymInfo();
m_ubBody = null;
m_ilGenerator = null;
// Default is managed IL. Manged IL has bit flag 0x0020 set off
m_dwMethodImplFlags = MethodImplAttributes.IL;
}
#endregion
#region Internal Members
internal void CheckContext(params Type[][] typess)
{
m_module.CheckContext(typess);
}
internal void CheckContext(params Type[] types)
{
m_module.CheckContext(types);
}
[System.Security.SecurityCritical] // auto-generated
internal void CreateMethodBodyHelper(ILGenerator il)
{
// Sets the IL of the method. An ILGenerator is passed as an argument and the method
// queries this instance to get all of the information which it needs.
if (il == null)
{
throw new ArgumentNullException("il");
}
Contract.EndContractBlock();
__ExceptionInfo[] excp;
int counter=0;
int[] filterAddrs;
int[] catchAddrs;
int[] catchEndAddrs;
Type[] catchClass;
int[] type;
int numCatch;
int start, end;
ModuleBuilder dynMod = (ModuleBuilder) m_module;
m_containingType.ThrowIfCreated();
if (m_bIsBaked)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodHasBody"));
}
if (il.m_methodBuilder != this && il.m_methodBuilder != null)
{
// you don't need to call CreateMethodBody when you get your ILGenerator
// through MethodBuilder::GetILGenerator.
//
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadILGeneratorUsage"));
}
ThrowIfShouldNotHaveBody();
if (il.m_ScopeTree.m_iOpenScopeCount != 0)
{
// There are still unclosed local scope
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_OpenLocalVariableScope"));
}
m_ubBody = il.BakeByteArray();
m_RVAFixups = il.GetRVAFixups();
m_mdMethodFixups = il.GetTokenFixups();
//Okay, now the fun part. Calculate all of the exceptions.
excp = il.GetExceptions();
m_numExceptions = CalculateNumberOfExceptions(excp);
if (m_numExceptions>0)
{
m_exceptions = new __ExceptionInstance[m_numExceptions];
for (int i=0; i 0 && (m_parameterTypes == null || position > m_parameterTypes.Length))
throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_ParamSequence"));
attributes = attributes & ~ParameterAttributes.ReservedMask;
return new ParameterBuilder(this, position, attributes, strParamName);
}
[System.Security.SecuritySafeCritical] // auto-generated
[Obsolete("An alternate API is available: Emit the MarshalAs custom attribute instead. http://go.microsoft.com/fwlink/?linkid=14202")]
public void SetMarshal(UnmanagedMarshal unmanagedMarshal)
{
ThrowIfGeneric ();
// set Marshal info for the return type
m_containingType.ThrowIfCreated();
if (m_retParam == null)
{
m_retParam = new ParameterBuilder(this, 0, 0, null);
}
m_retParam.SetMarshal(unmanagedMarshal);
}
private List m_symCustomAttrs;
private struct SymCustomAttr
{
public SymCustomAttr(String name, byte[] data)
{
m_name = name;
m_data = data;
}
public String m_name;
public byte[] m_data;
}
public void SetSymCustomAttribute(String name, byte[] data)
{
// Note that this API is rarely used. Support for custom attributes in PDB files was added in
// Whidbey and as of 8/2007 the only known user is the C# compiler. There seems to be little
// value to this for Reflection.Emit users since they can always use metadata custom attributes.
// Some versions of the symbol writer used in the CLR will ignore these entirely. This API has
// been removed from the Silverlight API surface area, but we should also consider removing it
// from future desktop product versions as well.
ThrowIfGeneric ();
// This is different from CustomAttribute. This is stored into the SymWriter.
m_containingType.ThrowIfCreated();
ModuleBuilder dynMod = (ModuleBuilder) m_module;
if ( dynMod.GetSymWriter() == null)
{
// Cannot SetSymCustomAttribute when it is not a debug module
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule"));
}
if (m_symCustomAttrs == null)
m_symCustomAttrs = new List();
m_symCustomAttrs.Add(new SymCustomAttr(name, data));
}
#if FEATURE_CAS_POLICY
[System.Security.SecuritySafeCritical] // auto-generated
public void AddDeclarativeSecurity(SecurityAction action, PermissionSet pset)
{
if (pset == null)
throw new ArgumentNullException("pset");
Contract.EndContractBlock();
ThrowIfGeneric ();
#pragma warning disable 618
if (!Enum.IsDefined(typeof(SecurityAction), action) ||
action == SecurityAction.RequestMinimum ||
action == SecurityAction.RequestOptional ||
action == SecurityAction.RequestRefuse)
{
throw new ArgumentOutOfRangeException("action");
}
#pragma warning restore 618
// cannot declarative security after type is created
m_containingType.ThrowIfCreated();
// Translate permission set into serialized format (uses standard binary serialization format).
byte[] blob = null;
int length = 0;
if (!pset.IsEmpty())
{
blob = pset.EncodeXml();
length = blob.Length;
}
// Write the blob into the metadata.
TypeBuilder.AddDeclarativeSecurity(m_module.GetNativeHandle(), MetadataTokenInternal, action, blob, length);
}
#endif // FEATURE_CAS_POLICY
public void CreateMethodBody(byte[] il,int count)
{
ThrowIfGeneric();
// Note that when user calls this function, there are a few information that client is
// not able to supply: local signature, exception handlers, max stack size, a list of Token fixup, a list of RVA fixup
if (m_bIsBaked)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodBaked"));
}
m_containingType.ThrowIfCreated();
if (il != null && (count < 0 || count > il.Length))
throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (il == null) {
m_ubBody = null;
return;
}
m_ubBody = new byte[count];
Array.Copy(il,m_ubBody,count);
m_bIsBaked=true;
}
[System.Security.SecuritySafeCritical] // auto-generated
public void SetImplementationFlags(MethodImplAttributes attributes)
{
ThrowIfGeneric ();
m_containingType.ThrowIfCreated ();
m_dwMethodImplFlags = attributes;
m_canBeRuntimeImpl = true;
TypeBuilder.SetMethodImpl(m_module.GetNativeHandle(), MetadataTokenInternal, attributes);
}
public ILGenerator GetILGenerator() {
ThrowIfGeneric ();
ThrowIfShouldNotHaveBody();
if (m_ilGenerator == null)
m_ilGenerator = new ILGenerator(this);
return m_ilGenerator;
}
public ILGenerator GetILGenerator(int size) {
ThrowIfGeneric ();
ThrowIfShouldNotHaveBody();
if (m_ilGenerator == null)
m_ilGenerator = new ILGenerator(this, size);
return m_ilGenerator;
}
private void ThrowIfShouldNotHaveBody() {
if ((m_dwMethodImplFlags&MethodImplAttributes.CodeTypeMask) != MethodImplAttributes.IL ||
(m_dwMethodImplFlags & MethodImplAttributes.Unmanaged) != 0 ||
(m_iAttributes & MethodAttributes.PinvokeImpl) != 0 ||
m_isDllImport)
{
// cannot attach method body if methodimpl is marked not marked as managed IL
//
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ShouldNotHaveMethodBody"));
}
}
public bool InitLocals
{
// Property is set to true if user wishes to have zero initialized stack frame for this method. Default to false.
get { ThrowIfGeneric (); return m_fInitLocals; }
set { ThrowIfGeneric (); m_fInitLocals = value; }
}
public Module GetModule()
{
return GetModuleBuilder();
}
public String Signature
{
[System.Security.SecuritySafeCritical] // auto-generated
get
{
return GetMethodSignature().ToString();
}
}
[System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
if (con == null)
throw new ArgumentNullException("con");
if (binaryAttribute == null)
throw new ArgumentNullException("binaryAttribute");
Contract.EndContractBlock();
ThrowIfGeneric();
TypeBuilder.DefineCustomAttribute(m_module, MetadataTokenInternal,
((ModuleBuilder)m_module).GetConstructorToken(con).Token,
binaryAttribute,
false, false);
if (IsKnownCA(con))
ParseCA(con, binaryAttribute);
}
[System.Security.SecuritySafeCritical] // auto-generated
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
{
if (customBuilder == null)
throw new ArgumentNullException("customBuilder");
Contract.EndContractBlock();
ThrowIfGeneric();
customBuilder.CreateCustomAttribute((ModuleBuilder)m_module, MetadataTokenInternal);
if (IsKnownCA(customBuilder.m_con))
ParseCA(customBuilder.m_con, customBuilder.m_blob);
}
// this method should return true for any and every ca that requires more work
// than just setting the ca
private bool IsKnownCA(ConstructorInfo con)
{
Type caType = con.DeclaringType;
if (caType == typeof(System.Runtime.CompilerServices.MethodImplAttribute)) return true;
else if (caType == typeof(DllImportAttribute)) return true;
else return false;
}
private void ParseCA(ConstructorInfo con, byte[] blob)
{
Type caType = con.DeclaringType;
if (caType == typeof(System.Runtime.CompilerServices.MethodImplAttribute))
{
// dig through the blob looking for the MethodImplAttributes flag
// that must be in the MethodCodeType field
// for now we simply set a flag that relaxes the check when saving and
// allows this method to have no body when any kind of MethodImplAttribute is present
m_canBeRuntimeImpl = true;
}
else if (caType == typeof(DllImportAttribute)) {
m_canBeRuntimeImpl = true;
m_isDllImport = true;
}
}
internal bool m_canBeRuntimeImpl = false;
internal bool m_isDllImport = false;
#endregion
void _MethodBuilder.GetTypeInfoCount(out uint pcTInfo)
{
throw new NotImplementedException();
}
void _MethodBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
{
throw new NotImplementedException();
}
void _MethodBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
{
throw new NotImplementedException();
}
void _MethodBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
{
throw new NotImplementedException();
}
}
internal class LocalSymInfo
{
// This class tracks the local variable's debugging information
// and namespace information with a given active lexical scope.
#region Internal Data Members
internal String[] m_strName;
internal byte[][] m_ubSignature;
internal int[] m_iLocalSlot;
internal int[] m_iStartOffset;
internal int[] m_iEndOffset;
internal int m_iLocalSymCount; // how many entries in the arrays are occupied
internal String[] m_namespace;
internal int m_iNameSpaceCount;
internal const int InitialSize = 16;
#endregion
#region Constructor
internal LocalSymInfo()
{
// initialize data variables
m_iLocalSymCount = 0;
m_iNameSpaceCount = 0;
}
#endregion
#region Private Members
private void EnsureCapacityNamespace()
{
if (m_iNameSpaceCount == 0)
{
m_namespace = new String[InitialSize];
}
else if (m_iNameSpaceCount == m_namespace.Length)
{
String [] strTemp = new String [checked(m_iNameSpaceCount * 2)];
Array.Copy(m_namespace, strTemp, m_iNameSpaceCount);
m_namespace = strTemp;
}
}
private void EnsureCapacity()
{
if (m_iLocalSymCount == 0)
{
// First time. Allocate the arrays.
m_strName = new String[InitialSize];
m_ubSignature = new byte[InitialSize][];
m_iLocalSlot = new int[InitialSize];
m_iStartOffset = new int[InitialSize];
m_iEndOffset = new int[InitialSize];
}
else if (m_iLocalSymCount == m_strName.Length)
{
// the arrays are full. Enlarge the arrays
// why aren't we just using lists here?
int newSize = checked(m_iLocalSymCount * 2);
int[] temp = new int [newSize];
Array.Copy(m_iLocalSlot, temp, m_iLocalSymCount);
m_iLocalSlot = temp;
temp = new int [newSize];
Array.Copy(m_iStartOffset, temp, m_iLocalSymCount);
m_iStartOffset = temp;
temp = new int [newSize];
Array.Copy(m_iEndOffset, temp, m_iLocalSymCount);
m_iEndOffset = temp;
String [] strTemp = new String [newSize];
Array.Copy(m_strName, strTemp, m_iLocalSymCount);
m_strName = strTemp;
byte[][] ubTemp = new byte[newSize][];
Array.Copy(m_ubSignature, ubTemp, m_iLocalSymCount);
m_ubSignature = ubTemp;
}
}
#endregion
#region Internal Members
internal void AddLocalSymInfo(String strName,byte[] signature,int slot,int startOffset,int endOffset)
{
// make sure that arrays are large enough to hold addition info
EnsureCapacity();
m_iStartOffset[m_iLocalSymCount] = startOffset;
m_iEndOffset[m_iLocalSymCount] = endOffset;
m_iLocalSlot[m_iLocalSymCount] = slot;
m_strName[m_iLocalSymCount] = strName;
m_ubSignature[m_iLocalSymCount] = signature;
checked {m_iLocalSymCount++; }
}
internal void AddUsingNamespace(String strNamespace)
{
EnsureCapacityNamespace();
m_namespace[m_iNameSpaceCount] = strNamespace;
checked { m_iNameSpaceCount++; }
}
internal virtual void EmitLocalSymInfo(ISymbolWriter symWriter)
{
int i;
for (i = 0; i < m_iLocalSymCount; i ++)
{
symWriter.DefineLocalVariable(
m_strName[i],
FieldAttributes.PrivateScope,
m_ubSignature[i],
SymAddressKind.ILOffset,
m_iLocalSlot[i],
0, // addr2 is not used yet
0, // addr3 is not used
m_iStartOffset[i],
m_iEndOffset[i]);
}
for (i = 0; i < m_iNameSpaceCount; i ++)
{
symWriter.UsingNamespace(m_namespace[i]);
}
}
#endregion
}
internal struct __ExceptionInstance
{
#region Internal Members
// Keep in [....] with unmanged structure.
internal int m_exceptionClass;
internal int m_startAddress;
internal int m_endAddress;
internal int m_filterAddress;
internal int m_handleAddress;
internal int m_handleEndAddress;
internal int m_type;
#endregion
#region Constructor
internal __ExceptionInstance(int start,int end,int filterAddr,int handle,int handleEnd,int type,int exceptionClass)
{
m_startAddress=start;
m_endAddress=end;
m_filterAddress = filterAddr;
m_handleAddress=handle;
m_handleEndAddress=handleEnd;
m_type=type;
m_exceptionClass = exceptionClass;
}
#endregion
#region Object Overrides
public override bool Equals(Object obj)
{
if (obj!=null && (obj is __ExceptionInstance)) {
__ExceptionInstance that = (__ExceptionInstance) obj;
return that.m_exceptionClass == m_exceptionClass &&
that.m_startAddress == m_startAddress && that.m_endAddress == m_endAddress &&
that.m_filterAddress == m_filterAddress &&
that.m_handleAddress == m_handleAddress && that.m_handleEndAddress == m_handleEndAddress;
}
else
return false;
}
public override int GetHashCode()
{
return m_exceptionClass ^ m_startAddress ^ m_endAddress ^ m_filterAddress ^ m_handleAddress ^ m_handleEndAddress ^ m_type;
}
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DescendantQuery.cs
- ContractTypeNameCollection.cs
- PasswordPropertyTextAttribute.cs
- SafeNativeHandle.cs
- DataGridViewColumnStateChangedEventArgs.cs
- ToolStripAdornerWindowService.cs
- NegotiateStream.cs
- LinqDataSourceStatusEventArgs.cs
- RuleConditionDialog.Designer.cs
- _OverlappedAsyncResult.cs
- SendMailErrorEventArgs.cs
- AuditLog.cs
- InkCanvasInnerCanvas.cs
- Serializer.cs
- SchemaImporterExtensionElement.cs
- AsyncDataRequest.cs
- graph.cs
- WebBaseEventKeyComparer.cs
- ResourceExpressionBuilder.cs
- EntitySet.cs
- PeerMaintainer.cs
- SerialPort.cs
- ComponentSerializationService.cs
- StreamReader.cs
- NamespaceCollection.cs
- TdsParserSessionPool.cs
- Configuration.cs
- BitmapSource.cs
- DtdParser.cs
- HashMembershipCondition.cs
- RestClientProxyHandler.cs
- WebPartManager.cs
- SqlCacheDependency.cs
- Empty.cs
- GeneralTransformCollection.cs
- WebPartZoneBase.cs
- ConfigXmlSignificantWhitespace.cs
- DefaultProxySection.cs
- SecurityAccessDeniedException.cs
- HuffModule.cs
- ManagedWndProcTracker.cs
- VisualTarget.cs
- RunClient.cs
- FunctionQuery.cs
- JulianCalendar.cs
- ScriptHandlerFactory.cs
- Executor.cs
- RenderingEventArgs.cs
- AssemblyHelper.cs
- SubMenuStyleCollection.cs
- PeerOutputChannel.cs
- Int32CollectionConverter.cs
- ListBoxItemWrapperAutomationPeer.cs
- NamespaceQuery.cs
- WinEventHandler.cs
- ValueExpressions.cs
- XPathDescendantIterator.cs
- FormParameter.cs
- XamlStyleSerializer.cs
- StylusPointDescription.cs
- Encoding.cs
- Dynamic.cs
- DataSourceViewSchemaConverter.cs
- CacheDependency.cs
- InfoCardCryptoHelper.cs
- CodeVariableReferenceExpression.cs
- Stream.cs
- LoginStatusDesigner.cs
- XmlIncludeAttribute.cs
- SqlRemoveConstantOrderBy.cs
- WinEventHandler.cs
- SizeChangedInfo.cs
- MergePropertyDescriptor.cs
- AdapterDictionary.cs
- versioninfo.cs
- SecureUICommand.cs
- HitTestFilterBehavior.cs
- SimpleWorkerRequest.cs
- FunctionCommandText.cs
- WindowsAltTab.cs
- ComPlusInstanceProvider.cs
- TextContainerHelper.cs
- Listbox.cs
- RowUpdatedEventArgs.cs
- AssemblyLoader.cs
- AttributeSetAction.cs
- RtType.cs
- LinkConverter.cs
- CollectionExtensions.cs
- DesignTimeTemplateParser.cs
- ToolBar.cs
- SqlProviderManifest.cs
- EqualityArray.cs
- ReachPrintTicketSerializerAsync.cs
- PointConverter.cs
- typedescriptorpermissionattribute.cs
- TypeListConverter.cs
- DockPattern.cs
- WorkflowViewService.cs
- SourceSwitch.cs