ModuleBuilder.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FXUpdate3074 / FXUpdate3074 / 1.1 / untmp / whidbey / QFE / ndp / clr / src / BCL / System / Reflection / Emit / ModuleBuilder.cs / 5 / ModuleBuilder.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 

namespace System.Reflection.Emit 
{ 
    using System.Runtime.InteropServices;
    using System; 
    using IList = System.Collections.IList;
    using System.Collections.Generic;
    using ArrayList = System.Collections.ArrayList;
    using CultureInfo = System.Globalization.CultureInfo; 
    using ResourceWriter = System.Resources.ResourceWriter;
    using IResourceWriter = System.Resources.IResourceWriter; 
    using System.Diagnostics.SymbolStore; 
    using System.Reflection;
    using System.Diagnostics; 
    using System.IO;
    using System.Security;
    using System.Security.Permissions;
    using System.Runtime.Serialization; 
    using System.Text;
    using System.Threading; 
    using System.Runtime.Versioning; 

 
    // deliberately not [serializable]
    [HostProtection(MayLeakOnAbort = true)]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(_ModuleBuilder))] 
[System.Runtime.InteropServices.ComVisible(true)]
    public class ModuleBuilder : Module, _ModuleBuilder 
    { 
        #region Internal Static Members
        static internal String UnmangleTypeName(String typeName) 
        {
            // Gets the original type name, without '+' name mangling.

            int i = typeName.Length - 1; 
            while (true)
            { 
                i = typeName.LastIndexOf('+', i); 
                if (i == -1)
                    break; 

                bool evenSlashes = true;
                int iSlash = i;
                while (typeName[--iSlash] == '\\') 
                    evenSlashes = !evenSlashes;
 
                // Even number of slashes means this '+' is a name separator 
                if (evenSlashes)
                    break; 

                i = iSlash;
            }
 
            return typeName.Substring(i + 1);
        } 
 
        #endregion
 
        #region Intenral Data Members
        internal ModuleBuilder m_internalModuleBuilder;
        // This is the "external" AssemblyBuilder
        // only the "external" ModuleBuilder has this set 
        private AssemblyBuilder m_assemblyBuilder;
        #endregion 
 
        #region Constructor
        // key: "internal" ModuleBuilder 
        // value: "external" ModuleBuilder
        private static readonly Dictionary s_moduleBuilders = new Dictionary();

        // This method returns self for Modules and "external" ModuleBuilders for ModuleBuilders 
        internal static Module GetModuleBuilder(Module module)
        { 
            ModuleBuilder internalModuleBuilder = module.InternalModule as ModuleBuilder; 
            if (internalModuleBuilder == null)
                return module; 

            ModuleBuilder externalModuleBuilder = null;
            lock (s_moduleBuilders)
            { 
                if (s_moduleBuilders.TryGetValue(internalModuleBuilder, out externalModuleBuilder))
                    // all ModuleBuilder objects created through DefineDynamicModule already 
                    // have corresponding "external" ModuleBuilders in s_moduleBuilders 
                    return externalModuleBuilder;
                else 
                    // there is no corresponding "external" ModuleBuilder for the manifest module
                    return internalModuleBuilder;
            }
        } 
        internal ModuleBuilder(AssemblyBuilder assemblyBuilder, ModuleBuilder internalModuleBuilder)
        { 
            m_internalModuleBuilder = internalModuleBuilder; 
            m_assemblyBuilder = assemblyBuilder;
            lock(s_moduleBuilders) 
                s_moduleBuilders[internalModuleBuilder] = this;
        }
        #endregion
 
        #region Private Members
        private Type GetType(String strFormat, Type baseType) 
        { 
            // This function takes a string to describe the compound type, such as "[,][]", and a baseType.
 
            if (strFormat == null || strFormat.Equals(String.Empty))
            {
                return baseType;
            } 

            // convert the format string to byte array and then call FormCompoundType 
            char[]      bFormat = strFormat.ToCharArray(); 
            return SymbolType.FormCompoundType(bFormat, baseType, 0);
 
        }


        internal void CheckContext(params Type[][] typess) 
        {
            ((AssemblyBuilder)Assembly).CheckContext(typess); 
        } 
        internal void CheckContext(params Type[] types)
        { 
            ((AssemblyBuilder)Assembly).CheckContext(types);
        }
        #endregion
 
        #region Internal Members
        private bool IsInternal 
        { 
            get
            { 
                return (m_internalModuleBuilder == null);
            }
        }
 
        private void DemandGrantedAssemblyPermission()
        { 
            AssemblyBuilder assemblyBuilder = (AssemblyBuilder)Assembly; 
            assemblyBuilder.DemandGrantedPermission();
        } 

        internal virtual Type FindTypeBuilderWithName(String strTypeName, bool ignoreCase)
        {
            int         size = m_TypeBuilderList.Count; 
            int         i;
            Type        typeTemp = null; 
 
            for (i = 0; i < size; i++)
            { 
                typeTemp = (Type) m_TypeBuilderList[i];
                if (ignoreCase == true)
                {
                    if (String.Compare(typeTemp.FullName, strTypeName, ((ignoreCase) ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)) == 0) 
                        break;
                } 
                else 
                {
                    if (typeTemp.FullName.Equals( strTypeName)) 
                        break;
                }
            }
            if (i == size) 
                typeTemp = null;
 
            return typeTemp; 
        }
 
        internal Type GetRootElementType(Type type)
        {
            // This function will walk compound type to the inner most BaseType. Such as returning int for "ptr[] int".
            if (type.IsByRef == false && type.IsPointer == false && type.IsArray == false) 
                return type;
 
            return GetRootElementType(type.GetElementType()); 
        }
 
        internal void SetEntryPoint(MethodInfo entryPoint)
        {
            // Sets the entry point of the module to be a given method.  If no entry point
            // is specified, calling EmitPEFile will generate a dll. 
            // AssemblyBuilder.SetEntryPoint has already demanded required permission
            m_EntryPoint = GetMethodTokenInternal(entryPoint); 
        } 

 
        internal void PreSave(String fileName,
            PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
        {
            if (Assembly.m_assemblyData.m_isSynchronized) 
            {
                lock(Assembly.m_assemblyData) 
                { 
                    PreSaveNoLock(fileName, portableExecutableKind, imageFileMachine);
                } 
            }
            else
            {
                PreSaveNoLock(fileName, portableExecutableKind, imageFileMachine); 
            }
        } 
 
        private void PreSaveNoLock(String fileName,
            PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine) 
        {
            // This is a helper called by AssemblyBuilder save to presave information for the persistable modules.
            Object      item;
            TypeBuilder typeBuilder; 
            if (m_moduleData.m_isSaved == true)
            { 
                // can only save once 
                throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
                    Environment.GetResourceString("InvalidOperation_ModuleHasBeenSaved"), 
                    m_moduleData.m_strModuleName));
            }

            if (m_moduleData.m_fGlobalBeenCreated == false && m_moduleData.m_fHasGlobal == true) 
                throw new NotSupportedException(Environment.GetResourceString("NotSupported_GlobalFunctionNotBaked"));
 
            int size = m_TypeBuilderList.Count; 
            for (int i=0; i.M ==> methDef = G.M 

                MethodOnTypeBuilderInstantiation motbi; 
                ConstructorOnTypeBuilderInstantiation cotbi; 

                if ((motbi = method as MethodOnTypeBuilderInstantiation) != null) 
                {
                    methDef = motbi.m_method;
                }
                else if ((cotbi = method as ConstructorOnTypeBuilderInstantiation) != null) 
                {
                    methDef = cotbi.m_ctor; 
                } 
                else if (method is MethodBuilder || method is ConstructorBuilder)
                { 
                    // methodInfo must be GenericMethodDefinition; trying to emit G.M
                    methDef = method;
                }
                else if (method.IsGenericMethod) 
                {
                    methDef = masmi.GetGenericMethodDefinition(); 
                    methDef = methDef.Module.ResolveMethod( 
                        methDef.MetadataTokenInternal,
                        methDef.GetGenericArguments(), 
                        methDef.DeclaringType != null ? methDef.DeclaringType.GetGenericArguments() : null) as MethodBase;
                }
                else
                { 
                    methDef = method;
                    methDef = method.Module.ResolveMethod( 
                        method.MetadataTokenInternal, 
                        null,
                        methDef.DeclaringType != null ? methDef.DeclaringType.GetGenericArguments() : null) as MethodBase; 
                }

                parameterTypes = methDef.GetParameterTypes();
                returnType = methDef.GetReturnType(); 
            }
            else 
            { 
                parameterTypes = method.GetParameterTypes();
                returnType = method.GetReturnType(); 
            }

            if (method.DeclaringType.IsGenericType)
            { 
                int length;
                byte[] sig = SignatureHelper.GetTypeSigToken(this, method.DeclaringType).InternalGetSignature(out length); 
                tkParent = InternalGetTypeSpecTokenWithBytes(sig, length); 
            }
            else if (method.Module.InternalModule != this.InternalModule) 
            {
                // Use typeRef as parent because the method's declaringType lives in a different assembly
                tkParent = GetTypeToken(method.DeclaringType).Token;
            } 
            else
            { 
                // Use methodDef as parent because the method lives in this assembly and its declaringType has no generic arguments 
                if (masmi != null)
                    tkParent = GetMethodToken(method as MethodInfo).Token; 
                else
                    tkParent = GetConstructorToken(method as ConstructorInfo).Token;
            }
 
            int sigLength;
            byte[] sigBytes = GetMemberRefSignature( 
                method.CallingConvention, returnType, parameterTypes, 
                optionalParameterTypes, cGenericParameters).InternalGetSignature(out sigLength);
 
            return InternalGetMemberRefFromSignature(tkParent, method.Name, sigBytes, sigLength);
        }

        internal SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType, 
            Type[] parameterTypes, Type[] optionalParameterTypes, int cGenericParameters)
        { 
            int cParams; 
            int i;
            SignatureHelper sig; 

            if (parameterTypes == null)
            {
                cParams = 0; 
            }
            else 
            { 
                cParams = parameterTypes.Length;
            } 

            sig = SignatureHelper.GetMethodSigHelper(this, call, returnType, cGenericParameters);

            for (i=0; i < cParams; i++) 
                sig.AddArgument(parameterTypes[i]);
 
            if (optionalParameterTypes != null && optionalParameterTypes.Length != 0) 
            {
                // add the sentinel 
                sig.AddSentinel();

                for (i=0; i < optionalParameterTypes.Length; i++)
                    sig.AddArgument(optionalParameterTypes[i]); 
            }
 
            return sig; 
        }
        #endregion 

        #region Module Overrides

        internal override bool IsDynamic() 
        {
            return true; 
        } 

        // m_internalModuleBuilder is null iff this is a "internal" ModuleBuilder 
        internal override Module InternalModule
        {
            get
            { 
                if (IsInternal)
                    return this; 
                else 
                    return m_internalModuleBuilder;
            } 
        }

        internal override Assembly GetAssemblyInternal()
        { 
            if (!IsInternal)
                // return the "external" AssemblyBuilder 
                return m_assemblyBuilder; 
            else
                // return the "internal" AssemblyBuilder 
                return _GetAssemblyInternal();
        }

        public override Type[] GetTypes() 
        {
            if (Assembly.m_assemblyData.m_isSynchronized) 
            { 
                lock(Assembly.m_assemblyData)
                { 
                    return GetTypesNoLock();
                }
            }
            else 
            {
                return GetTypesNoLock(); 
            } 
        }
 
        internal Type[] GetTypesNoLock()
        {
            int size = m_TypeBuilderList.Count;
            List typeList = new List(size); 
            TypeBuilder tmpTypeBldr;
 
            bool canReturnTypeBuilder = false; 
            if (IsInternal)
            { 
                try
                {
                    DemandGrantedAssemblyPermission();
                    canReturnTypeBuilder = true; 
                }
                catch (SecurityException) 
                { 
                    canReturnTypeBuilder = false;
                } 
            }
            else
            {
                canReturnTypeBuilder = true; 
            }
 
            for (int i = 0; i < size; i++) 
            {
                EnumBuilder enumBldr = m_TypeBuilderList[i] as EnumBuilder; 

                if (enumBldr != null)
                    tmpTypeBldr = enumBldr.m_typeBuilder;
                else 
                    tmpTypeBldr = m_TypeBuilderList[i] as TypeBuilder;
 
                if (tmpTypeBldr != null) 
                {
                    // We should return TypeBuilders only if this is "external" 
                    // ModuleBuilder or if we its granted permission
                    if (tmpTypeBldr.m_hasBeenCreated)
                        typeList.Add(tmpTypeBldr.UnderlyingSystemType);
                    else if (canReturnTypeBuilder) 
                        typeList.Add(tmpTypeBldr);
                } 
                else 
                {
                    // RuntimeType case: This will happen in TlbImp. 
                    typeList.Add((Type) m_TypeBuilderList[i]);
                }
            }
 
            return typeList.ToArray();
        } 
 
[System.Runtime.InteropServices.ComVisible(true)]
        public override Type GetType(String className) 
        {
            return GetType(className, false, false);
        }
 
[System.Runtime.InteropServices.ComVisible(true)]
        public override Type GetType(String className, bool ignoreCase) 
        { 
            return GetType(className, false, ignoreCase);
        } 

[System.Runtime.InteropServices.ComVisible(true)]
        public override Type GetType(String className, bool throwOnError, bool ignoreCase)
        { 
            if (Assembly.m_assemblyData.m_isSynchronized)
            { 
                lock(Assembly.m_assemblyData) 
                {
                    return GetTypeNoLock(className, throwOnError, ignoreCase); 
                }
            }
            else
            { 
                return GetTypeNoLock(className, throwOnError, ignoreCase);
            } 
        } 

        private Type GetTypeNoLock(String className, bool throwOnError, bool ignoreCase) 
        {
            // public API to to a type. The reason that we need this function override from module
            // is because clients might need to get foo[] when foo is being built. For example, if
            // foo class contains a data member of type foo[]. 
            // This API first delegate to the Module.GetType implementation. If succeeded, great!
            // If not, we have to look up the current module to find the TypeBuilder to represent the base 
            // type and form the Type object for "foo[,]". 

            // Module.GetType() will verify className. 
            Type baseType = base.GetType(className, throwOnError, ignoreCase);
            if (baseType != null)
                return baseType;
 
            // Now try to see if we contain a TypeBuilder for this type or not.
            // Might have a compound type name, indicated via an unescaped 
            // '[', '*' or '&'. Split the name at this point. 
            String baseName = null;
            String parameters = null; 
            int startIndex = 0;

            while (startIndex <= className.Length)
            { 
                // Are there any possible special characters left?
                int i = className.IndexOfAny(new char[]{'[', '*', '&'}, startIndex); 
                if (i == -1) 
                {
                    // No, type name is simple. 
                    baseName = className;
                    parameters = null;
                    break;
                } 

                // Found a potential special character, but it might be escaped. 
                int slashes = 0; 
                for (int j = i - 1; j >= 0 && className[j] == '\\'; j--)
                    slashes++; 

                // Odd number of slashes indicates escaping.
                if (slashes % 2 == 1)
                { 
                    startIndex = i + 1;
                    continue; 
                } 

                // Found the end of the base type name. 
                baseName = className.Substring(0, i);
                parameters = className.Substring(i);
                break;
            } 

            // If we didn't find a basename yet, the entire class name is 
            // the base name and we don't have a composite type. 
            if (baseName == null)
            { 
                baseName = className;
                parameters = null;
            }
 
            baseName = baseName.Replace(@"\\",@"\").Replace(@"\[",@"[").Replace(@"\*",@"*").Replace(@"\&",@"&");
 
            if (parameters != null) 
            {
                // try to see if reflection can find the base type. It can be such that reflection 
                // does not support the complex format string yet!

                baseType = base.GetType(baseName, false, ignoreCase);
            } 

            bool canReturnTypeBuilder = false; 
            if (IsInternal) 
            {
                try 
                {
                    DemandGrantedAssemblyPermission();
                    canReturnTypeBuilder = true;
                } 
                catch (SecurityException)
                { 
                    canReturnTypeBuilder = false; 
                }
            } 
            else
            {
                canReturnTypeBuilder = true;
            } 

            if (baseType == null && canReturnTypeBuilder) 
            { 
                // try to find it among the unbaked types.
                // starting with the current module first of all. 
                // We only do this is this is an "external" ModuleBuilder
                //   or if we have its granted permission
                baseType = FindTypeBuilderWithName(baseName, ignoreCase);
                if (baseType == null && Assembly is AssemblyBuilder) 
                {
                    // now goto Assembly level to find the type. 
                    int         size; 
                    ArrayList   modList;
 
                    modList = Assembly.m_assemblyData.m_moduleBuilderList;
                    size = modList.Count;
                    for (int i = 0; i < size && baseType == null; i++)
                    { 
                        ModuleBuilder mBuilder = (ModuleBuilder) modList[i];
                        baseType = mBuilder.FindTypeBuilderWithName(baseName, ignoreCase); 
                    } 
                }
            } 

            if (baseType == null)
                return null;
 
            if (parameters == null)
                return baseType; 
 
            return GetType(parameters, baseType);
        } 

        public override String FullyQualifiedName
        {
            [ResourceExposure(ResourceScope.Machine)] 
            [ResourceConsumption(ResourceScope.Machine)]
            get 
            { 
                String fullyQualifiedName = m_moduleData.m_strFileName;
                if (fullyQualifiedName == null) 
                    return null;
                if (Assembly.m_assemblyData.m_strDir != null)
                {
                    fullyQualifiedName = Path.Combine(Assembly.m_assemblyData.m_strDir, fullyQualifiedName); 
                    fullyQualifiedName = Path.GetFullPath(fullyQualifiedName);
                } 
 
                if (Assembly.m_assemblyData.m_strDir != null && fullyQualifiedName != null)
                { 
                    new FileIOPermission( FileIOPermissionAccess.PathDiscovery, fullyQualifiedName ).Demand();
                }

                return fullyQualifiedName; 
            }
        } 
 
        #endregion
 
        #region Public Members

        #region Define Type
        public TypeBuilder DefineType(String name) 
        {
            if (IsInternal) 
                DemandGrantedAssemblyPermission(); 

            if (Assembly.m_assemblyData.m_isSynchronized) 
            {
                lock(Assembly.m_assemblyData)
                {
                    return DefineTypeNoLock(name); 
                }
            } 
            else 
            {
                return DefineTypeNoLock(name); 
            }
        }

        private TypeBuilder DefineTypeNoLock(String name) 
        {
            TypeBuilder typeBuilder; 
            typeBuilder =  new TypeBuilder(name, TypeAttributes.NotPublic, null, null, this, PackingSize.Unspecified, null); 
            m_TypeBuilderList.Add(typeBuilder);
            return typeBuilder; 
        }

        public TypeBuilder DefineType(String name, TypeAttributes attr)
        { 
            if (IsInternal)
                DemandGrantedAssemblyPermission(); 
 
            if (Assembly.m_assemblyData.m_isSynchronized)
            { 
                lock(Assembly.m_assemblyData)
                {
                    return DefineTypeNoLock(name, attr);
                } 
            }
            else 
            { 
                return DefineTypeNoLock(name, attr);
            } 
        }

        private TypeBuilder DefineTypeNoLock(String name, TypeAttributes attr)
        { 
            TypeBuilder typeBuilder;
            typeBuilder =  new TypeBuilder(name, attr, null, null, this, PackingSize.Unspecified, null); 
            m_TypeBuilderList.Add(typeBuilder); 
            return typeBuilder;
        } 

        public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent)
        {
            if (IsInternal) 
                DemandGrantedAssemblyPermission();
 
            if (Assembly.m_assemblyData.m_isSynchronized) 
            {
                lock(Assembly.m_assemblyData) 
                {
                    return DefineTypeNoLock(name, attr, parent);
                }
            } 
            else
            { 
                return DefineTypeNoLock(name, attr, parent); 
            }
        } 

        private TypeBuilder DefineTypeNoLock(String name, TypeAttributes attr, Type parent)
        {
            CheckContext(parent); 

            TypeBuilder typeBuilder; 
 
            typeBuilder =  new TypeBuilder(
                name, attr, parent, null, this, PackingSize.Unspecified, null); 
            m_TypeBuilderList.Add(typeBuilder);
            return typeBuilder;
        }
 
        public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent, int typesize)
        { 
            if (IsInternal) 
                DemandGrantedAssemblyPermission();
 
            if (Assembly.m_assemblyData.m_isSynchronized)
            {
                lock(Assembly.m_assemblyData)
                { 
                    return DefineTypeNoLock(name, attr, parent, typesize);
                } 
            } 
            else
            { 
                return DefineTypeNoLock(name, attr, parent, typesize);
            }
        }
 
        private TypeBuilder DefineTypeNoLock(String name, TypeAttributes attr, Type parent, int typesize)
        { 
            TypeBuilder typeBuilder; 
            typeBuilder = new TypeBuilder(name, attr, parent, this, PackingSize.Unspecified, typesize, null);
            m_TypeBuilderList.Add(typeBuilder); 
            return typeBuilder;
        }

        public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent, PackingSize packingSize, int typesize) 
        {
            if (IsInternal) 
                DemandGrantedAssemblyPermission(); 

            if (Assembly.m_assemblyData.m_isSynchronized) 
            {
                lock(Assembly.m_assemblyData)
                {
                    return DefineTypeNoLock(name, attr, parent, packingSize, typesize); 
                }
            } 
            else 
            {
                return DefineTypeNoLock(name, attr, parent, packingSize, typesize); 
            }
        }

        private TypeBuilder DefineTypeNoLock(String name, TypeAttributes attr, Type parent, PackingSize packingSize, int typesize) 
        {
            TypeBuilder typeBuilder; 
            typeBuilder = new TypeBuilder(name, attr, parent, this, packingSize, typesize, null); 
            m_TypeBuilderList.Add(typeBuilder);
            return typeBuilder; 
        }

[System.Runtime.InteropServices.ComVisible(true)]
        public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent, Type[] interfaces) 
        {
            if (IsInternal) 
                DemandGrantedAssemblyPermission(); 

            if (Assembly.m_assemblyData.m_isSynchronized) 
            {
                lock(Assembly.m_assemblyData)
                {
                    return DefineTypeNoLock(name, attr, parent, interfaces); 
                }
            } 
            else 
            {
                return DefineTypeNoLock(name, attr, parent, interfaces); 
            }
        }

        private TypeBuilder DefineTypeNoLock(String name, TypeAttributes attr, Type parent, Type[] interfaces) 
        {
            TypeBuilder typeBuilder; 
            typeBuilder =  new TypeBuilder(name, attr, parent, interfaces, this, PackingSize.Unspecified, null); 
            m_TypeBuilderList.Add(typeBuilder);
            return typeBuilder; 
        }

        #endregion
 
        #region Define Enum
        public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent, PackingSize packsize) 
        { 
            if (IsInternal)
                DemandGrantedAssemblyPermission(); 

            if (Assembly.m_assemblyData.m_isSynchronized)
            {
                lock(Assembly.m_assemblyData) 
                {
                    return DefineTypeNoLock(name, attr, parent, packsize); 
                } 
            }
            else 
            {
                return DefineTypeNoLock(name, attr, parent, packsize);
            }
        } 

        private TypeBuilder DefineTypeNoLock(String name, TypeAttributes attr, Type parent, PackingSize packsize) 
        { 
            TypeBuilder typeBuilder;
            typeBuilder = new TypeBuilder(name, attr, parent, null, this, packsize, null); 
            m_TypeBuilderList.Add(typeBuilder);
            return typeBuilder;
        }
 
        public EnumBuilder DefineEnum(String name, TypeAttributes visibility, Type underlyingType)
        { 
            if (IsInternal) 
                DemandGrantedAssemblyPermission();
 
            CheckContext(underlyingType);
            if (Assembly.m_assemblyData.m_isSynchronized)
            {
                lock(Assembly.m_assemblyData) 
                {
                    return DefineEnumNoLock(name, visibility, underlyingType); 
                } 
            }
            else 
            {
                return DefineEnumNoLock(name, visibility, underlyingType);
            }
        } 

        private EnumBuilder DefineEnumNoLock(String name, TypeAttributes visibility, Type underlyingType) 
        { 
            EnumBuilder enumBuilder;
            enumBuilder = new EnumBuilder(name, underlyingType, visibility, this); 
            m_TypeBuilderList.Add(enumBuilder);
            return enumBuilder;
        }
 
        #endregion
 
        #region Define Resource 
        public IResourceWriter DefineResource(String name, String description)
        { 
            // Define embedded managed resource to be stored in this module

            return DefineResource(name, description, ResourceAttributes.Public);
        } 

        public IResourceWriter DefineResource(String name, String description, ResourceAttributes attribute) 
        { 
            // Define embedded managed resource to be stored in this module
 
            if (IsInternal)
                DemandGrantedAssemblyPermission();

            if (Assembly.m_assemblyData.m_isSynchronized) 
            {
                lock(Assembly.m_assemblyData) 
                { 
                    return DefineResourceNoLock(name, description, attribute);
                } 
            }
            else
            {
                return DefineResourceNoLock(name, description, attribute); 
            }
        } 
 
        private IResourceWriter DefineResourceNoLock(String name, String description, ResourceAttributes attribute)
        { 
            // Define embedded managed resource to be stored in this module


            if (IsTransient()) 
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer"));
 
            if (name == null) 
                throw new ArgumentNullException("name");
            if (name.Length == 0) 
                throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");

            Assembly assembly = this.Assembly;
            if (assembly is AssemblyBuilder) 
            {
                AssemblyBuilder asmBuilder = (AssemblyBuilder)assembly; 
                if (asmBuilder.IsPersistable()) 
                {
                    asmBuilder.m_assemblyData.CheckResNameConflict(name); 

                    MemoryStream stream = new MemoryStream();
                    ResourceWriter resWriter = new ResourceWriter(stream);
                    ResWriterData resWriterData = new ResWriterData( resWriter, stream, name, String.Empty, String.Empty, attribute); 

                    // chain it to the embedded resource list 
                    resWriterData.m_nextResWriter = m_moduleData.m_embeddedRes; 
                    m_moduleData.m_embeddedRes = resWriterData;
                    return resWriter; 
                }
                else
                {
                    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer")); 
                }
            } 
            else 
            {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer")); 
            }
        }

        public void DefineManifestResource(String name, Stream stream, ResourceAttributes attribute) 
        {
            if (name == null) 
                throw new ArgumentNullException("name"); 

            if (stream == null) 
                throw new ArgumentNullException("stream");

            if (IsInternal)
                DemandGrantedAssemblyPermission(); 

            // Define embedded managed resource to be stored in this module 
 
            if (Assembly.m_assemblyData.m_isSynchronized)
            { 
                lock(Assembly.m_assemblyData)
                {
                    DefineManifestResourceNoLock(name, stream, attribute);
                } 
            }
            else 
            { 
                DefineManifestResourceNoLock(name, stream, attribute);
            } 
        }

        private void DefineManifestResourceNoLock(String name, Stream stream, ResourceAttributes attribute)
        { 
            // Define embedded managed resource to be stored in this module
 
 
            if (IsTransient())
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer")); 

            if (name == null)
                throw new ArgumentNullException("name");
            if (name.Length == 0) 
                throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
 
            Assembly assembly = this.Assembly; 
            if (assembly is AssemblyBuilder)
            { 
                AssemblyBuilder asmBuilder = (AssemblyBuilder)assembly;
                if (asmBuilder.IsPersistable())
                {
                    asmBuilder.m_assemblyData.CheckResNameConflict(name); 

                    ResWriterData resWriterData = new ResWriterData( null, stream, name, String.Empty, String.Empty, attribute); 
 
                    // chain it to the embedded resource list
                    resWriterData.m_nextResWriter = m_moduleData.m_embeddedRes; 
                    m_moduleData.m_embeddedRes = resWriterData;
                }
                else
                { 
                    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer"));
                } 
            } 
            else
            { 
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer"));
            }
        }
 

        public void DefineUnmanagedResource(Byte[] resource) 
        { 
            if (IsInternal)
                DemandGrantedAssemblyPermission(); 

            if (Assembly.m_assemblyData.m_isSynchronized)
            {
                lock (Assembly.m_assemblyData) 
                {
                    DefineUnmanagedResourceInternalNoLock(resource); 
                } 
            }
            else 
            {
                DefineUnmanagedResourceInternalNoLock(resource);
            }
        } 

        internal void DefineUnmanagedResourceInternalNoLock(Byte[] resource) 
        { 
            if (m_moduleData.m_strResourceFileName != null || m_moduleData.m_resourceBytes != null)
                throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined")); 

            if (resource == null)
                throw new ArgumentNullException("resource");
 
            m_moduleData.m_resourceBytes = new byte[resource.Length];
            System.Array.Copy(resource, m_moduleData.m_resourceBytes, resource.Length); 
        } 

        [ResourceExposure(ResourceScope.Machine)] 
        [ResourceConsumption(ResourceScope.Machine)]
        public void DefineUnmanagedResource(String resourceFileName)
        {
            if (IsInternal) 
                DemandGrantedAssemblyPermission();
 
            if (Assembly.m_assemblyData.m_isSynchronized) 
            {
                lock (Assembly.m_assemblyData) 
                {
                    DefineUnmanagedResourceFileInternalNoLock(resourceFileName);
                }
            } 
            else
            { 
                DefineUnmanagedResourceFileInternalNoLock(resourceFileName); 
            }
        } 

        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)]
        internal void DefineUnmanagedResourceFileInternalNoLock(String resourceFileName) 
        {
            if (m_moduleData.m_resourceBytes != null || m_moduleData.m_strResourceFileName != null) 
                throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined")); 

            if (resourceFileName == null) 
                throw new ArgumentNullException("resourceFileName");

            // Check caller has the right to read the file.
            string strFullFileName; 
            strFullFileName = Path.GetFullPath(resourceFileName);
            new FileIOPermission(FileIOPermissionAccess.Read, strFullFileName).Demand(); 
 
            new EnvironmentPermission(PermissionState.Unrestricted).Assert();
            try 
            {
                if (File.Exists(resourceFileName) == false)
                    throw new FileNotFoundException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString(
                        "IO.FileNotFound_FileName"), 
                        resourceFileName), resourceFileName);
            } 
            finally 
            {
                CodeAccessPermission.RevertAssert(); 
            }

            m_moduleData.m_strResourceFileName = strFullFileName;
        } 
        #endregion
 
        #region Define Global Method 
        public MethodBuilder DefineGlobalMethod(String name, MethodAttributes attributes, Type returnType, Type[] parameterTypes)
        { 
            return DefineGlobalMethod(name, attributes, CallingConventions.Standard, returnType, parameterTypes);
        }

        public MethodBuilder DefineGlobalMethod(String name, MethodAttributes attributes, CallingConventions callingConvention, 
            Type returnType, Type[] parameterTypes)
        { 
            return DefineGlobalMethod(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null); 
        }
 
        public MethodBuilder DefineGlobalMethod(String name, MethodAttributes attributes, CallingConventions callingConvention,
            Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
            Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
        { 
            if (IsInternal)
                DemandGrantedAssemblyPermission(); 
 
            if (Assembly.m_assemblyData.m_isSynchronized)
            { 
                lock(Assembly.m_assemblyData)
                {
                    return DefineGlobalMethodNoLock(name, attributes, callingConvention, returnType,
                                                    requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, 
                                                    parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
                } 
            } 
            else
            { 
                return DefineGlobalMethodNoLock(name, attributes, callingConvention, returnType,
                                                requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers,
                                                parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
            } 
        }
 
        private MethodBuilder DefineGlobalMethodNoLock(String name, MethodAttributes attributes, CallingConventions callingConvention, 
            Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
            Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers) 
        {
            CheckContext(returnType);
            CheckContext(requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, parameterTypes);
            CheckContext(requiredParameterTypeCustomModifiers); 
            CheckContext(optionalParameterTypeCustomModifiers);
 
            if (m_moduleData.m_fGlobalBeenCreated == true) 
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GlobalsHaveBeenCreated"));
 
            if (name == null)
                throw new ArgumentNullException("name");

            if (name.Length == 0) 
                throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
 
            if ((attributes & MethodAttributes.Static) == 0) 
                throw new ArgumentException(Environment.GetResourceString("Argument_GlobalFunctionHasToBeStatic"));
 
            m_moduleData.m_fHasGlobal = true;

            return m_moduleData.m_globalTypeBuilder.DefineMethod(name, attributes, callingConvention,
                returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, 
                parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
        } 
 
        public MethodBuilder DefinePInvokeMethod(String name, String dllName, MethodAttributes attributes,
            CallingConventions callingConvention, Type returnType, Type[] parameterTypes, 
            CallingConvention nativeCallConv, CharSet nativeCharSet)
        {
            return DefinePInvokeMethod(name, dllName, name, attributes, callingConvention, returnType, parameterTypes, nativeCallConv, nativeCharSet);
        } 

        public MethodBuilder DefinePInvokeMethod(String name, String dllName, String entryName, MethodAttributes attributes, 
            CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, 
            CharSet nativeCharSet)
        { 
            if (IsInternal)
                DemandGrantedAssemblyPermission();

            if (Assembly.m_assemblyData.m_isSynchronized) 
            {
                lock(Assembly.m_assemblyData) 
                { 
                    return DefinePInvokeMethodNoLock(name, dllName, entryName, attributes, callingConvention,
                                                     returnType, parameterTypes, nativeCallConv, nativeCharSet); 
                }
            }
            else
            { 
                return DefinePInvokeMethodNoLock(name, dllName, entryName, attributes, callingConvention,
                                                 returnType, parameterTypes, nativeCallConv, nativeCharSet); 
            } 
        }
 
        private MethodBuilder DefinePInvokeMethodNoLock(String name, String dllName, String entryName, MethodAttributes attributes,
            CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv,
            CharSet nativeCharSet)
        { 
            CheckContext(returnType);
            CheckContext(parameterTypes); 
 
            //Global methods must be static.
            if ((attributes & MethodAttributes.Static) == 0) 
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_GlobalFunctionHasToBeStatic"));
            }
            m_moduleData.m_fHasGlobal = true; 
            return m_moduleData.m_globalTypeBuilder.DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType, parameterTypes, nativeCallConv, nativeCharSet);
        } 
 
        public void CreateGlobalFunctions()
        { 
            if (IsInternal)
                DemandGrantedAssemblyPermission();

            if (Assembly.m_assemblyData.m_isSynchronized) 
            {
                lock(Assembly.m_assemblyData) 
                { 
                    CreateGlobalFunctionsNoLock();
                } 
            }
            else
            {
                CreateGlobalFunctionsNoLock(); 
            }
        } 
 
        private void CreateGlobalFunctionsNoLock()
        { 
            if (m_moduleData.m_fGlobalBeenCreated)
            {
                // cannot create globals twice
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule")); 
            }
            m_moduleData.m_globalTypeBuilder.CreateType(); 
            m_moduleData.m_fGlobalBeenCreated = true; 
        }
 
        #endregion

        #region Define Data
        public FieldBuilder DefineInitializedData(String name, byte[] data, FieldAttributes attributes) 
        {
            // This method will define an initialized Data in .sdata. 
            // We will create a fake TypeDef to represent the data with size. This TypeDef 
            // will be the signature for the Field.
 
            if (IsInternal)
                DemandGrantedAssemblyPermission();

            if (Assembly.m_assemblyData.m_isSynchronized) 
            {
                lock(Assembly.m_assemblyData) 
                { 
                    return DefineInitializedDataNoLock(name, data, attributes);
                } 
            }
            else
            {
                return DefineInitializedDataNoLock(name, data, attributes); 
            }
        } 
 
        private FieldBuilder DefineInitializedDataNoLock(String name, byte[] data, FieldAttributes attributes)
        { 
            // This method will define an initialized Data in .sdata.
            // We will create a fake TypeDef to represent the data with size. This TypeDef
            // will be the signature for the Field.
            if (m_moduleData.m_fGlobalBeenCreated == true) 
            {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GlobalsHaveBeenCreated")); 
            } 

            m_moduleData.m_fHasGlobal = true; 
            return m_moduleData.m_globalTypeBuilder.DefineInitializedData(name, data, attributes);
        }

        public FieldBuilder DefineUninitializedData(String name, int size, FieldAttributes attributes) 
        {
            if (IsInternal) 
                DemandGrantedAssemblyPermission(); 

            if (Assembly.m_assemblyData.m_isSynchronized) 
            {
                lock(Assembly.m_assemblyData)
                {
                    return DefineUninitializedDataNoLock(name, size, attributes); 
                }
            } 
            else 
            {
                return DefineUninitializedDataNoLock(name, size, attributes); 
            }
        }

        private FieldBuilder DefineUninitializedDataNoLock(String name, int size, FieldAttributes attributes) 
        {
            // This method will define an uninitialized Data in .sdata. 
            // We will create a fake TypeDef to represent the data with size. This TypeDef 
            // will be the signature for the Field.
 
            if (m_moduleData.m_fGlobalBeenCreated == true)
            {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GlobalsHaveBeenCreated"));
            } 

            m_moduleData.m_fHasGlobal = true; 
            return m_moduleData.m_globalTypeBuilder.DefineUninitializedData(name, size, attributes); 
        }
 
        #endregion

        #region GetToken
        // For a generic type definition, we should return the token for the generic type definition itself in two cases: 
        //   1. GetTypeToken
        //   2. ldtoken (see ILGenerator) 
        // For all other occasions we should return the generic type instantiated on its formal parameters. 
        internal TypeToken GetTypeTokenInternal(Type type)
        { 
            return GetTypeTokenInternal(type, false);
        }

        internal TypeToken GetTypeTokenInternal(Type type, bool getGenericDefinition) 
        {
            if (Assembly.m_assemblyData.m_isSynchronized) 
            { 
                lock(Assembly.m_assemblyData)
                { 
                    return GetTypeTokenWorkerNoLock(type, getGenericDefinition);
                }
            }
            else 
            {
                return GetTypeTokenWorkerNoLock(type, getGenericDefinition); 
            } 
        }
 
        public TypeToken GetTypeToken(Type type)
        {
            return GetTypeTokenInternal(type, true);
        } 

        private TypeToken GetTypeTokenWorkerNoLock(Type type, bool getGenericDefinition) 
        { 
            CheckContext(type);
 
            // Return a token for the class relative to the Module.  Tokens
            // are used to indentify objects when the objects are used in IL
            // instructions.  Tokens are always relative to the Module.  For example,
            // the token value for System.String is likely to be different from 
            // Module to Module.  Calling GetTypeToken will cause a reference to be
            // added to the Module.  This reference becomes a perminate part of the Module, 
            // multiple calles to this method with the same class have no additional side affects. 
            // This function is optimized to use the TypeDef token if Type is within the same module.
            // We should also be aware of multiple dynamic modules and multiple implementation of Type!!! 

            TypeToken tkToken;
            bool isSameModule;
            Module refedModule; 
            String strRefedModuleFileName = String.Empty;
 
            // assume that referenced module is non-transient. Only if the referenced module is dynamic, 
            // and transient, this variable will be set to true.
            bool isRefedModuleTransient = false; 

            if (type == null)
                throw new ArgumentNullException("type");
 
            refedModule = GetModuleBuilder(type.Module);
            isSameModule = refedModule.Equals(this); 
 
            if (type.IsByRef)
                throw new ArgumentException(Environment.GetResourceString("Argument_CannotGetTypeTokenForByRef")); 

            if ((type.IsGenericType && (!type.IsGenericTypeDefinition || !getGenericDefinition)) ||
                type.IsGenericParameter ||
                type.IsArray || 
                type.IsPointer)
            { 
                int length; 
                byte[] sig = SignatureHelper.GetTypeSigToken(this, type).InternalGetSignature(out length);
                return new TypeToken(InternalGetTypeSpecTokenWithBytes(sig, length)); 
            }

            if (isSameModule)
            { 
                // no need to do anything additional other than defining the TypeRef Token
                TypeBuilder typeBuilder; 
 
                EnumBuilder enumBuilder = type as EnumBuilder;
                if (enumBuilder != null) 
                    typeBuilder = enumBuilder.m_typeBuilder;
                else
                    typeBuilder = type as TypeBuilder;
 
                if (typeBuilder != null)
                { 
                    // optimization: if the type is defined in this module, 
                    // just return the token
                    // 
                    return typeBuilder.TypeToken;
                }
                else if (type is GenericTypeParameterBuilder)
                { 
                    return new TypeToken(type.MetadataTokenInternal);
                } 
 
                return new TypeToken(GetTypeRefNested(type, this, String.Empty));
            } 

            // After this point, the referenced module is not the same as the referencing
            // module.
 
            ModuleBuilder refedModuleBuilder = refedModule as ModuleBuilder;
            if (refedModuleBuilder != null) 
            { 
                if (refedModuleBuilder.IsTransient())
                { 
                    isRefedModuleTransient = true;
                }
                // get the referenced module's file name
                strRefedModuleFileName = refedModuleBuilder.m_moduleData.m_strFileName; 
            }
            else 
                strRefedModuleFileName = refedModule.ScopeName; 

            // We cannot have a non-transient module referencing to a transient module. 
            if (IsTransient() == false && isRefedModuleTransient)
            {

                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadTransientModuleReference")); 
            }
 
            tkToken = new TypeToken(GetTypeRefNested(type, refedModule, strRefedModuleFileName)); 
            return tkToken;
        } 

        public TypeToken GetTypeToken(String name)
        {
            // Return a token for the class relative to the Module. 
            // Module.GetType() verifies name
 
            // Unfortunately, we will need to load the Type and then call GetTypeToken in 
            // order to correctly track the assembly reference information.
 
            return GetTypeToken(base.GetType(name, false, true));
        }

        public MethodToken GetMethodToken(MethodInfo method) 
        {
            if (Assembly.m_assemblyData.m_isSynchronized) 
            { 
                lock(Assembly.m_assemblyData)
                { 
                    return GetMethodTokenNoLock(method, true);
                }
            }
            else 
            {
                return GetMethodTokenNoLock(method, true); 
            } 
        }
 
        internal MethodToken GetMethodTokenInternal(MethodInfo method)
        {
            if (Assembly.m_assemblyData.m_isSynchronized)
            { 
                lock(Assembly.m_assemblyData)
                { 
                    return GetMethodTokenNoLock(method, false); 
                }
            } 
            else
            {
                return GetMethodTokenNoLock(method, false);
            } 
        }
 
        // For a method on a generic type, we should return the methoddef token on the generic type definition in two cases 
        //   1. GetMethodToken
        //   2. ldtoken (see ILGenerator) 
        // For all other occasions we should return the method on the generic type instantiated on the formal parameters.
        private MethodToken GetMethodTokenNoLock(MethodInfo method, bool getGenericTypeDefinition)
        {
            // Return a MemberRef token if MethodInfo is not defined in this module. Or 
            // return the MethodDef token.
 
            int tr; 
            int mr = 0;
 
            if (method == null)
                throw new ArgumentNullException("method");

            if (method is MethodBuilder) 
            {
                if (method.Module.InternalModule == this.InternalModule) 
                    return new MethodToken(method.MetadataTokenInternal); 

                if (method.DeclaringType == null) 
                    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotImportGlobalFromDifferentModule"));

                // method is defined in a different module
                tr = getGenericTypeDefinition ? GetTypeToken(method.DeclaringType).Token : GetTypeTokenInternal(method.DeclaringType).Token; 
                mr = InternalGetMemberRef(method.DeclaringType.Module, tr, method.MetadataTokenInternal);
            } 
            else if (method is MethodOnTypeBuilderInstantiation) 
            {
                return new MethodToken(GetMemberRefToken(method, null)); 
            }
            else if (method is SymbolMethod)
            {
                SymbolMethod symMethod = method as SymbolMethod; 

                if (symMethod.GetModule() == this) 
                    return symMethod.GetToken(); 

                // form the method token 
                return symMethod.GetToken(this);
            }
            else
            { 
                Type declaringType = method.DeclaringType;
 
                // We need to get the TypeRef tokens 
                if (declaringType == null)
                    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotImportGlobalFromDifferentModule")); 

                if (declaringType.IsArray == true)
                {
                    // use reflection to build signature to work around the E_T_VAR problem in EEClass 
                    ParameterInfo[] paramInfo = method.GetParameters();
 
                    Type[] tt = new Type[paramInfo.Length]; 

                    for (int i = 0; i < paramInfo.Length; i++) 
                        tt[i] = paramInfo[i].ParameterType;

                    return GetArrayMethodToken(declaringType, method.Name, method.CallingConvention, method.ReturnType, tt);
                } 
                else if (method is RuntimeMethodInfo)
                { 
                tr = getGenericTypeDefinition ? GetTypeToken(method.DeclaringType).Token : GetTypeTokenInternal(method.DeclaringType).Token; 
                    mr = InternalGetMemberRefOfMethodInfo(tr, method.GetMethodHandle());
                } 
                else
                {
                    // some user derived ConstructorInfo
                    // go through the slower code path, i.e. retrieve parameters and form signature helper. 
                    ParameterInfo[] parameters = method.GetParameters();
 
                    Type[] parameterTypes = new Type[parameters.Length]; 
                    Type[][] requiredCustomModifiers = new Type[parameterTypes.Length][];
                    Type[][] optionalCustomModifiers = new Type[parameterTypes.Length][]; 

                    for (int i = 0; i < parameters.Length; i++)
                    {
                        parameterTypes[i] = parameters[i].ParameterType; 
                        requiredCustomModifiers[i] = parameters[i].GetRequiredCustomModifiers();
                        optionalCustomModifiers[i] = parameters[i].GetOptionalCustomModifiers(); 
                    } 

                    tr = getGenericTypeDefinition ? GetTypeToken(method.DeclaringType).Token : GetTypeTokenInternal(method.DeclaringType).Token; 

                    SignatureHelper sigHelp;

                    try 
                    {
                        sigHelp = SignatureHelper.GetMethodSigHelper( 
                        this, method.CallingConvention, method.ReturnType, 
                        method.ReturnParameter.GetRequiredCustomModifiers(), method.ReturnParameter.GetOptionalCustomModifiers(),
                        parameterTypes, requiredCustomModifiers, optionalCustomModifiers); 
                    }
                    catch(NotImplementedException)
                    {
                        // Legacy code deriving from MethodInfo may not have implemented ReturnParameter. 
                        sigHelp = SignatureHelper.GetMethodSigHelper(this, method.ReturnType, parameterTypes);
                    } 
 
                    int length;
                    byte[] sigBytes = sigHelp.InternalGetSignature(out length); 
                    mr = InternalGetMemberRefFromSignature(tr, method.Name, sigBytes, length);
                }
            }
 
            return new MethodToken(mr);
        } 
 
        public MethodToken GetArrayMethodToken(Type arrayClass, String methodName, CallingConventions callingConvention,
            Type returnType, Type[] parameterTypes) 
        {
            if (Assembly.m_assemblyData.m_isSynchronized)
            {
                lock(Assembly.m_assemblyData) 
                {
                    return GetArrayMethodTokenNoLock(arrayClass, methodName, callingConvention, returnType, parameterTypes); 
                } 
            }
            else 
            {
                return GetArrayMethodTokenNoLock(arrayClass, methodName, callingConvention, returnType, parameterTypes);
            }
        } 

        private MethodToken GetArrayMethodTokenNoLock(Type arrayClass, String methodName, CallingConventions callingConvention, 
            Type returnType, Type[] parameterTypes) 
        {
            CheckContext(returnType, arrayClass); 
            CheckContext(parameterTypes);

            // Return a token for the MethodInfo for a method on an Array.  This is primarily
            // used to get the LoadElementAddress method. 

            Type baseType; 
            int baseToken; 
            int length;
 
            if (arrayClass == null)
                throw new ArgumentNullException("arrayClass");

            if (methodName == null) 
                throw new ArgumentNullException("methodName");
 
            if (methodName.Length == 0) 
                throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "methodName");
 
            if (arrayClass.IsArray == false)
                throw new ArgumentException(Environment.GetResourceString("Argument_HasToBeArrayClass"));

            SignatureHelper sigHelp = SignatureHelper.GetMethodSigHelper( 
                this, callingConvention, returnType, null, null, parameterTypes, null, null);
 
            byte[] sigBytes = sigHelp.InternalGetSignature(out length); 

            // track the TypeRef of the array base class 
            for (baseType = arrayClass; baseType.IsArray; baseType = baseType.GetElementType());
            baseToken = GetTypeTokenInternal(baseType).Token;

            TypeToken typeSpec = GetTypeTokenInternal(arrayClass); 

            return new MethodToken(nativeGetArrayMethodToken( 
                typeSpec.Token, methodName, sigBytes, length, baseToken /* TODO: Remove */)); 
        }
 
        public MethodInfo GetArrayMethod(Type arrayClass, String methodName, CallingConventions callingConvention,
            Type returnType, Type[] parameterTypes)
        {
            CheckContext(returnType, arrayClass); 
            CheckContext(parameterTypes);
 
            // GetArrayMethod is useful when you have an array of a type whose definition has not been completed and 
            // you want to access methods defined on Array. For example, you might define a type and want to define a
            // method that takes an array of the type as a parameter. In order to access the elements of the array, 
            // you will need to call methods of the Array class.

            MethodToken token = GetArrayMethodToken(arrayClass, methodName, callingConvention, returnType, parameterTypes);
 
            return new SymbolMethod(this, token, arrayClass, methodName, callingConvention, returnType, parameterTypes);
        } 
 
        [System.Runtime.InteropServices.ComVisible(true)]
        public MethodToken GetConstructorToken(ConstructorInfo con) 
        {
            // Return a token for the ConstructorInfo relative to the Module.
            return InternalGetConstructorToken(con, false);
        } 

        public FieldToken GetFieldToken(FieldInfo field) 
        { 
            if (Assembly.m_assemblyData.m_isSynchronized)
            { 
                lock(Assembly.m_assemblyData)
                {
                    return GetFieldTokenNoLock(field);
                } 
            }
            else 
            { 
                return GetFieldTokenNoLock(field);
            } 
        }

        private FieldToken GetFieldTokenNoLock(FieldInfo field)
        { 
            int     tr;
            int     mr = 0; 
 
            if (field == null) {
                throw new ArgumentNullException("con"); 
            }
            else if (field is FieldBuilder)
            {
                FieldBuilder fdBuilder = (FieldBuilder) field; 

                if (field.DeclaringType != null && field.DeclaringType.IsGenericType) 
                { 
                    int length;
                    byte[] sig = SignatureHelper.GetTypeSigToken(this, field.DeclaringType).InternalGetSignature(out length); 
                    tr = InternalGetTypeSpecTokenWithBytes(sig, length);
                    mr = InternalGetMemberRef(this, tr, fdBuilder.GetToken().Token);
                }
                else if (fdBuilder.GetTypeBuilder().Module.InternalModule.Equals(this.InternalModule)) 
                {
                    // field is defined in the same module 
                    return fdBuilder.GetToken(); 
                }
                else 
                {
                    // field is defined in a different module
                    if (field.DeclaringType == null)
                    { 
                        throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotImportGlobalFromDifferentModule"));
                    } 
                    tr = GetTypeTokenInternal(field.DeclaringType).Token; 
                    mr = InternalGetMemberRef(field.ReflectedType.Module, tr, fdBuilder.GetToken().Token);
                } 
            }
            else if (field is RuntimeFieldInfo)
            {
                // FieldInfo is not an dynamic field 

                // We need to get the TypeRef tokens 
                if (field.DeclaringType == null) 
                {
                    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotImportGlobalFromDifferentModule")); 
                }

                if (field.DeclaringType != null && field.DeclaringType.IsGenericType)
                { 
                    int length;
                    byte[] sig = SignatureHelper.GetTypeSigToken(this, field.DeclaringType).InternalGetSignature(out length); 
                    tr = InternalGetTypeSpecTokenWithBytes(sig, length); 
                    mr = InternalGetMemberRefOfFieldInfo(tr, field.DeclaringType.GetTypeHandleInternal(), field.MetadataTokenInternal);
                } 
                else
                {
                    tr = GetTypeTokenInternal(field.DeclaringType).Token;
                    mr = InternalGetMemberRefOfFieldInfo(tr, field.DeclaringType.GetTypeHandleInternal(), field.MetadataTokenInternal); 
                }
            } 
            else if (field is FieldOnTypeBuilderInstantiation) 
            {
                FieldInfo fb = ((FieldOnTypeBuilderInstantiation)field).FieldInfo; 
                int length;
                byte[] sig = SignatureHelper.GetTypeSigToken(this, field.DeclaringType).InternalGetSignature(out length);
                tr = InternalGetTypeSpecTokenWithBytes(sig, length);
                mr = InternalGetMemberRef(fb.ReflectedType.Module, tr, fb.MetadataTokenInternal); 
            }
            else 
            { 
                // user defined FieldInfo
                tr = GetTypeTokenInternal(field.ReflectedType).Token; 

                SignatureHelper sigHelp = SignatureHelper.GetFieldSigHelper(this);

                sigHelp.AddArgument(field.FieldType, field.GetRequiredCustomModifiers(), field.GetOptionalCustomModifiers()); 

                int length; 
                byte[] sigBytes = sigHelp.InternalGetSignature(out length); 

                mr = InternalGetMemberRefFromSignature(tr, field.Name, sigBytes, length); 
            }

            return new FieldToken(mr, field.GetType());
        } 

        public StringToken GetStringConstant(String str) 
        { 
            // Returns a token representing a String constant.  If the string
            // value has already been defined, the existing token will be returned. 
            return new StringToken(InternalGetStringConstant(str));
        }

        public SignatureToken GetSignatureToken(SignatureHelper sigHelper) 
        {
            // Define signature token given a signature helper. This will define a metadata 
            // token for the signature described by SignatureHelper. 

            int sigLength; 
            byte[] sigBytes;

            if (sigHelper == null)
            { 
                throw new ArgumentNullException("sigHelper");
            } 
 
            // get the signature in byte form
            sigBytes = sigHelper.InternalGetSignature(out sigLength); 
            return new SignatureToken(TypeBuilder.InternalGetTokenFromSig(this, sigBytes, sigLength), this);
        }
        public SignatureToken GetSignatureToken(byte[] sigBytes, int sigLength)
        { 
            byte[] localSigBytes = null;
 
            if (sigBytes == null) 
                throw new ArgumentNullException("sigBytes");
 
            localSigBytes = new byte[sigBytes.Length];
            Array.Copy(sigBytes, localSigBytes, sigBytes.Length);

            return new SignatureToken(TypeBuilder.InternalGetTokenFromSig(this, localSigBytes, sigLength), this); 
        }
 
        #endregion 

        #region Other 
[System.Runtime.InteropServices.ComVisible(true)]
        public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
        {
            if (IsInternal) 
                DemandGrantedAssemblyPermission();
 
            if (con == null) 
                throw new ArgumentNullException("con");
            if (binaryAttribute == null) 
                throw new ArgumentNullException("binaryAttribute");

            TypeBuilder.InternalCreateCustomAttribute(
                1,                                          // This is hard coding the module token to 1 
                this.GetConstructorToken(con).Token,
                binaryAttribute, 
                this, 
                false);
        } 

        public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
        {
            if (IsInternal) 
                DemandGrantedAssemblyPermission();
 
            if (customBuilder == null) 
            {
                throw new ArgumentNullException("customBuilder"); 
            }

            customBuilder.CreateCustomAttribute(this, 1);   // This is hard coding the module token to 1
        } 

        public ISymbolWriter GetSymWriter() 
        { 
            if (IsInternal)
                DemandGrantedAssemblyPermission(); 

            return m_iSymWriter;
        }
 
        public ISymbolDocumentWriter DefineDocument(String url, Guid language, Guid languageVendor, Guid documentType)
        { 
            if (IsInternal) 
                DemandGrantedAssemblyPermission();
 
            if (Assembly.m_assemblyData.m_isSynchronized)
            {
                lock(Assembly.m_assemblyData)
                { 
                    return DefineDocumentNoLock(url, language, languageVendor, documentType);
                } 
            } 
            else
            { 
                return DefineDocumentNoLock(url, language, languageVendor, documentType);
            }
        }
 
        private ISymbolDocumentWriter DefineDocumentNoLock(String url, Guid language, Guid languageVendor, Guid documentType)
        { 
            if (m_iSymWriter == null) 
            {
                // Cannot DefineDocument when it is not a debug module 
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule"));
            }

            return m_iSymWriter.DefineDocument(url, language, languageVendor, documentType); 
        }
 
        public void SetUserEntryPoint(MethodInfo entryPoint) 
        {
            if (IsInternal) 
                DemandGrantedAssemblyPermission();

            if (Assembly.m_assemblyData.m_isSynchronized)
            { 
                lock(Assembly.m_assemblyData)
                { 
                    SetUserEntryPointNoLock(entryPoint); 
                }
            } 
            else
            {
                SetUserEntryPointNoLock(entryPoint);
            } 
        }
 
        private void SetUserEntryPointNoLock(MethodInfo entryPoint) 
        {
            // Set the user entry point. Compiler may generate startup stub before calling user main. 
            // The startup stub will be the entry point. While the user "main" will be the user entry
            // point so that debugger will not step into the compiler entry point.

            if (entryPoint == null) 
            {
                throw new ArgumentNullException("entryPoint"); 
            } 

            if (m_iSymWriter == null) 
            {
                // Cannot set entry point when it is not a debug module
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule"));
            } 

            if (entryPoint.DeclaringType != null) 
            { 
                if (entryPoint.Module.InternalModule != this.InternalModule)
                { 
                    // you cannot pass in a MethodInfo that is not contained by this ModuleBuilder
                    throw new InvalidOperationException(Environment.GetResourceString("Argument_NotInTheSameModuleBuilder"));
                }
            } 
            else
            { 
                // unfortunately this check is missing for global function passed in as RuntimeMethodInfo. 
                // The problem is that Reflection does not
                // allow us to get the containing module giving a global function 
                MethodBuilder mb = entryPoint as MethodBuilder;
                if (mb != null && mb.GetModule().InternalModule != this.InternalModule)
                {
                    // you cannot pass in a MethodInfo that is not contained by this ModuleBuilder 
                    throw new InvalidOperationException(Environment.GetResourceString("Argument_NotInTheSameModuleBuilder"));
                } 
            } 

            // get the metadata token value and create the SymbolStore's token value class 
            SymbolToken       tkMethod = new SymbolToken(GetMethodTokenInternal(entryPoint).Token);

            // set the UserEntryPoint
            m_iSymWriter.SetUserEntryPoint(tkMethod); 
        }
 
        public void SetSymCustomAttribute(String name, byte[] data) 
        {
            if (IsInternal) 
                DemandGrantedAssemblyPermission();

            if (Assembly.m_assemblyData.m_isSynchronized)
            { 
                lock(Assembly.m_assemblyData)
                { 
                    SetSymCustomAttributeNoLock(name, data); 
                }
            } 
            else
            {
                SetSymCustomAttributeNoLock(name, data);
            } 
        }
 
        private void SetSymCustomAttributeNoLock(String name, byte[] data) 
        {
            if (m_iSymWriter == null) 
            {
                // Cannot SetSymCustomAttribute when it is not a debug module
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule"));
            } 

 
 
            //SymbolToken      tk = new SymbolToken();
            //m_iSymWriter.SetSymAttribute(tk, name, data); 
        }

        public bool IsTransient()
        { 
            return m_moduleData.IsTransient();
        } 
 
        #endregion
 
        #endregion

        void _ModuleBuilder.GetTypeInfoCount(out uint pcTInfo)
        { 
            throw new NotImplementedException();
        } 
 
        void _ModuleBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
        { 
            throw new NotImplementedException();
        }

        void _ModuleBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) 
        {
            throw new NotImplementedException(); 
        } 

        void _ModuleBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) 
        {
            throw new NotImplementedException();
        }
    } 
}
 
 

 



 

 
 

 



 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK