Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / clr / src / BCL / System / Reflection / Emit / ModuleBuilder.cs / 7 / 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 Dictionarys_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>.MmethDef = 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; ListtypeList = 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. // // ==--== 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>.MmethDef = 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; ListtypeList = 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.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- BookmarkManager.cs
- PlaceHolder.cs
- OletxDependentTransaction.cs
- IconEditor.cs
- StrokeRenderer.cs
- ImportRequest.cs
- LeaseManager.cs
- TypeExtensionConverter.cs
- XPathCompileException.cs
- SafeNativeHandle.cs
- UpdatePanel.cs
- WsatEtwTraceListener.cs
- CroppedBitmap.cs
- ExpressionLink.cs
- GradientStop.cs
- Int32CollectionConverter.cs
- NavigationProperty.cs
- DbDeleteCommandTree.cs
- WriteFileContext.cs
- HttpSysSettings.cs
- PolicyDesigner.cs
- ISAPIApplicationHost.cs
- ComplexLine.cs
- ElapsedEventArgs.cs
- InlineUIContainer.cs
- ControlBuilderAttribute.cs
- ItemAutomationPeer.cs
- HtmlShim.cs
- HtmlButton.cs
- TreeNodeStyle.cs
- CaseInsensitiveComparer.cs
- ElementsClipboardData.cs
- ExtendedPropertyDescriptor.cs
- odbcmetadatacollectionnames.cs
- EventItfInfo.cs
- RijndaelManaged.cs
- DefaultSection.cs
- LineServicesCallbacks.cs
- Timer.cs
- DnsEndPoint.cs
- GridView.cs
- WebScriptEnablingElement.cs
- DataGridViewComboBoxColumn.cs
- PointKeyFrameCollection.cs
- IndentedWriter.cs
- SizeIndependentAnimationStorage.cs
- ProcessModelInfo.cs
- EventLogStatus.cs
- DebugView.cs
- EventProviderBase.cs
- FlowDocumentPage.cs
- dataprotectionpermissionattribute.cs
- GcSettings.cs
- MasterPageBuildProvider.cs
- MemberInfoSerializationHolder.cs
- SettingsBase.cs
- SemanticAnalyzer.cs
- TextSpanModifier.cs
- CoreSwitches.cs
- FacetDescription.cs
- AdPostCacheSubstitution.cs
- UnaryOperationBinder.cs
- RemotingException.cs
- EntityDataSourceUtil.cs
- DynamicDataResources.Designer.cs
- OleDbParameter.cs
- RouteParser.cs
- AudioFileOut.cs
- Zone.cs
- uribuilder.cs
- DBCommand.cs
- SqlClientWrapperSmiStreamChars.cs
- RegexCode.cs
- AsyncStreamReader.cs
- CompositionAdorner.cs
- SafeIUnknown.cs
- FixedTextPointer.cs
- ColumnCollection.cs
- Stylesheet.cs
- WindowsStreamSecurityElement.cs
- CategoriesDocumentFormatter.cs
- StyleModeStack.cs
- ErrorStyle.cs
- EntityClientCacheKey.cs
- TimeSpanSecondsConverter.cs
- DocumentXmlWriter.cs
- ColorBlend.cs
- UriScheme.cs
- ComponentDispatcherThread.cs
- ImageListStreamer.cs
- ProtocolsSection.cs
- Bitmap.cs
- FacetValueContainer.cs
- WebPartVerbsEventArgs.cs
- IndependentAnimationStorage.cs
- PathSegmentCollection.cs
- RSAPKCS1SignatureDeformatter.cs
- ApplyTemplatesAction.cs
- OutArgumentConverter.cs
- WeakReference.cs