We need you! We're working hard on the next version of Developer Fusion - Let us know what you think we should be up to!

The Labs \ Source Viewer \ SSCLI \ System.Reflection.Emit \ AssemblyBuilder

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace System.Reflection.Emit
  16. {
  17.     using System;
  18.     using System.IO;
  19.     using System.Diagnostics.SymbolStore;
  20.     using System.Reflection;
  21.     using System.Diagnostics;
  22.     using System.Resources;
  23.     using System.Security.Permissions;
  24.     using System.Runtime.Remoting.Activation;
  25.     using CultureInfo = System.Globalization.CultureInfo;
  26.     using System.Runtime.Serialization;
  27.     using System.Security;
  28.     using System.Threading;
  29.     using System.Runtime.CompilerServices;
  30.     using System.Runtime.InteropServices;
  31.     using System.Runtime.Versioning;
  32.    
  33.     // AssemblyBuilder class.
  34.     // deliberately not [serializable]
  35.     [HostProtection(MayLeakOnAbort = true)]
  36.     [ClassInterface(ClassInterfaceType.None)]
  37.     [ComDefaultInterface(typeof(_AssemblyBuilder))]
  38.     [ComVisible(true)]
  39.     public sealed class AssemblyBuilder : Assembly, _AssemblyBuilder
  40.     {
  41.        
  42. /**********************************************
  43.         *
  44.         * Defines a named dynamic module. It is an error to define multiple
  45.         * modules within an Assembly with the same name. This dynamic module is
  46.         * a transient module.
  47.         *
  48.         **********************************************/       
  49.         public ModuleBuilder DefineDynamicModule(string name)
  50.         {
  51.             CodeAccessPermission.DemandInternal(PermissionType.ReflectionEmit);
  52.            
  53.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  54.             return DefineDynamicModuleInternal(name, false, ref stackMark);
  55.         }
  56.        
  57.         // specify if emit symbol info or not
  58.         public ModuleBuilder DefineDynamicModule(string name, bool emitSymbolInfo)
  59.         {
  60.             CodeAccessPermission.DemandInternal(PermissionType.ReflectionEmit);
  61.            
  62.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  63.             return DefineDynamicModuleInternal(name, emitSymbolInfo, ref stackMark);
  64.         }
  65.        
  66.             // specify if emit symbol info or not
  67.         internal ModuleBuilder DefineDynamicModuleInternal(string name, bool emitSymbolInfo, ref StackCrawlMark stackMark)
  68.         {
  69.             BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.DefineDynamicModule( " + name + " )");
  70.            
  71.             BCLDebug.Assert(m_assemblyData != null, "m_assemblyData is null in DefineDynamicModuleInternal");
  72.            
  73.             if (name == null)
  74.                 throw new ArgumentNullException("name");
  75.             if (name.Length == 0)
  76.                 throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
  77.             if (name[0] == '\0')
  78.                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidName"), "name");
  79.            
  80.             m_assemblyData.CheckNameConflict(name);
  81.            
  82.             // create the dynamic module
  83.             ModuleBuilder dynModule = nDefineDynamicModule(this, emitSymbolInfo, name, ref stackMark);
  84.             ISymbolWriter writer = null;
  85.            
  86.             if (emitSymbolInfo) {
  87.                 // create the default SymWriter
  88.                 Assembly assem = LoadISymWrapper();
  89.                 Type symWriter = assem.GetType("System.Diagnostics.SymbolStore.SymWriter", true, false);
  90.                 if (symWriter != null && !symWriter.IsVisible)
  91.                     symWriter = null;
  92.                
  93.                 if (symWriter == null) {
  94.                     // cannot find SymWriter
  95.                     throw new ExecutionEngineException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString(ResId.MissingType), "SymWriter"));
  96.                 }
  97.                 try {
  98.                     (new PermissionSet(PermissionState.Unrestricted)).Assert();
  99.                     writer = (ISymbolWriter)Activator.CreateInstance(symWriter);
  100.                 }
  101.                 finally {
  102.                     CodeAccessPermission.RevertAssert();
  103.                 }
  104.             }
  105.            
  106.             dynModule.Init(name, null, writer);
  107.             m_assemblyData.AddModule(dynModule);
  108.             return dynModule;
  109.         }
  110.        
  111.         private Assembly LoadISymWrapper()
  112.         {
  113.             if (m_assemblyData.m_ISymWrapperAssembly != null)
  114.                 return m_assemblyData.m_ISymWrapperAssembly;
  115.            
  116.             Assembly assem = Assembly.Load("ISymWrapper, Version=" + ThisAssembly.Version + ", Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken);
  117.            
  118.             m_assemblyData.m_ISymWrapperAssembly = assem;
  119.             return assem;
  120.         }
  121.        
  122. /**********************************************
  123.         *
  124.         * Defines a named dynamic module. It is an error to define multiple
  125.         * modules within an Assembly with the same name. No symbol information
  126.         * will be emitted.
  127.         *
  128.         **********************************************/       
  129.         public ModuleBuilder DefineDynamicModule(string name, string fileName)
  130.         {
  131.             CodeAccessPermission.DemandInternal(PermissionType.ReflectionEmit);
  132.            
  133.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  134.            
  135.             // delegate to the next DefineDynamicModule
  136.             return DefineDynamicModuleInternal(name, fileName, false, ref stackMark);
  137.         }
  138.        
  139. /**********************************************
  140.         *
  141.         * Emit symbol information if emitSymbolInfo is true using the
  142.         * default symbol writer interface.
  143.         * An exception will be thrown if the assembly is transient.
  144.         *
  145.         **********************************************/       
  146.             // module name
  147.             // module file name
  148.         // specify if emit symbol info or not
  149.         public ModuleBuilder DefineDynamicModule(string name, string fileName, bool emitSymbolInfo)
  150.         {
  151.             CodeAccessPermission.DemandInternal(PermissionType.ReflectionEmit);
  152.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  153.             return DefineDynamicModuleInternal(name, fileName, emitSymbolInfo, ref stackMark);
  154.         }
  155.        
  156.             // module name
  157.             // module file name
  158.             // specify if emit symbol info or not
  159.         // stack crawl mark used to find caller
  160.         private ModuleBuilder DefineDynamicModuleInternal(string name, string fileName, bool emitSymbolInfo, ref StackCrawlMark stackMark)
  161.         {
  162.             if (m_assemblyData.m_isSynchronized) {
  163.                 lock (m_assemblyData) {
  164.                     return DefineDynamicModuleInternalNoLock(name, fileName, emitSymbolInfo, ref stackMark);
  165.                 }
  166.             }
  167.             else {
  168.                 return DefineDynamicModuleInternalNoLock(name, fileName, emitSymbolInfo, ref stackMark);
  169.             }
  170.         }
  171.        
  172.         public override bool ReflectionOnly {
  173.             get { return base.ReflectionOnly; }
  174.         }
  175.        
  176.         internal void CheckContext(params Type[][] typess)
  177.         {
  178.             if (typess == null)
  179.                 return;
  180.            
  181.             foreach (Type[] types in typess)
  182.                 if (types != null)
  183.                     CheckContext(types);
  184.         }
  185.        
  186.         internal void CheckContext(params Type[] types)
  187.         {
  188.             if (types == null)
  189.                 return;
  190.            
  191.             foreach (Type type in types) {
  192.                 if (type == null || type.Module.Assembly == typeof(object).Module.Assembly)
  193.                     return;
  194.                 if (type.Module.Assembly.ReflectionOnly && !ReflectionOnly)
  195.                     throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Arugment_EmitMixedContext1"), type.AssemblyQualifiedName));
  196.                
  197.                 if (!type.Module.Assembly.ReflectionOnly && ReflectionOnly)
  198.                     throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Arugment_EmitMixedContext2"), type.AssemblyQualifiedName));
  199.             }
  200.         }
  201.        
  202.             // module name
  203.             // module file name
  204.             // specify if emit symbol info or not
  205.         // stack crawl mark used to find caller
  206.         private ModuleBuilder DefineDynamicModuleInternalNoLock(string name, string fileName, bool emitSymbolInfo, ref StackCrawlMark stackMark)
  207.         {
  208.             BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.DefineDynamicModule( " + name + ", " + fileName + ", " + emitSymbolInfo + " )");
  209.             if (m_assemblyData.m_access == AssemblyBuilderAccess.Run) {
  210.                 // Error! You cannot define a persistable module within a transient data.
  211.                 throw new NotSupportedException(Environment.GetResourceString("Argument_BadPersistableModuleInTransientAssembly"));
  212.             }
  213.            
  214.             if (m_assemblyData.m_isSaved == true) {
  215.                 // assembly has been saved before!
  216.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotAlterAssembly"));
  217.             }
  218.            
  219.             if (name == null)
  220.                 throw new ArgumentNullException("name");
  221.             if (name.Length == 0)
  222.                 throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
  223.             if (name[0] == '\0')
  224.                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidName"), "name");
  225.            
  226.             if (fileName == null)
  227.                 throw new ArgumentNullException("fileName");
  228.             if (fileName.Length == 0)
  229.                 throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "fileName");
  230.             if (!String.Equals(fileName, Path.GetFileName(fileName)))
  231.                 throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "fileName");
  232.            
  233.             m_assemblyData.CheckNameConflict(name);
  234.             m_assemblyData.CheckFileNameConflict(fileName);
  235.            
  236.             // ecall to create the dynamic module
  237.             ModuleBuilder dynModule = nDefineDynamicModule(this, emitSymbolInfo, fileName, ref stackMark);
  238.             ISymbolWriter writer = null;
  239.            
  240.             if (emitSymbolInfo) {
  241.                 // create the default SymWriter
  242.                 Assembly assem = LoadISymWrapper();
  243.                 Type symWriter = assem.GetType("System.Diagnostics.SymbolStore.SymWriter", true, false);
  244.                 if (symWriter != null && !symWriter.IsVisible)
  245.                     symWriter = null;
  246.                
  247.                 if (symWriter == null) {
  248.                     // cannot find SymWriter
  249.                     throw new ExecutionEngineException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("MissingType"), "SymWriter"));
  250.                 }
  251.                 try {
  252.                     (new PermissionSet(PermissionState.Unrestricted)).Assert();
  253.                     writer = (ISymbolWriter)Activator.CreateInstance(symWriter);
  254.                 }
  255.                 finally {
  256.                     CodeAccessPermission.RevertAssert();
  257.                 }
  258.                
  259.             }
  260.            
  261.             // initialize the dynamic module's managed side information
  262.             dynModule.Init(name, fileName, writer);
  263.             m_assemblyData.AddModule(dynModule);
  264.             return dynModule;
  265.         }
  266.        
  267.        
  268. /**********************************************
  269.         *
  270.         * Define stand alone managed resource for Assembly
  271.         *
  272.         **********************************************/       
  273.         [ResourceExposure(ResourceScope.Machine)]
  274.         [ResourceConsumption(ResourceScope.Machine)]
  275.         public IResourceWriter DefineResource(string name, string description, string fileName)
  276.         {
  277.             return DefineResource(name, description, fileName, ResourceAttributes.Public);
  278.         }
  279.        
  280. /**********************************************
  281.         *
  282.         * Define stand alone managed resource for Assembly
  283.         *
  284.         **********************************************/       
  285.         [ResourceExposure(ResourceScope.Machine)]
  286.         [ResourceConsumption(ResourceScope.Machine)]
  287.         public IResourceWriter DefineResource(string name, string description, string fileName, ResourceAttributes attribute)
  288.         {
  289.             if (m_assemblyData.m_isSynchronized) {
  290.                 lock (m_assemblyData) {
  291.                     return DefineResourceNoLock(name, description, fileName, attribute);
  292.                 }
  293.             }
  294.             else {
  295.                 return DefineResourceNoLock(name, description, fileName, attribute);
  296.             }
  297.         }
  298.        
  299.         [ResourceExposure(ResourceScope.Machine)]
  300.         [ResourceConsumption(ResourceScope.Machine)]
  301.         private IResourceWriter DefineResourceNoLock(string name, string description, string fileName, ResourceAttributes attribute)
  302.         {
  303.             CodeAccessPermission.DemandInternal(PermissionType.ReflectionEmit);
  304.             BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.DefineResource( " + name + ", " + fileName + ")");
  305.            
  306.             if (name == null)
  307.                 throw new ArgumentNullException("name");
  308.             if (name.Length == 0)
  309.                 throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), name);
  310.             if (fileName == null)
  311.                 throw new ArgumentNullException("fileName");
  312.             if (fileName.Length == 0)
  313.                 throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "fileName");
  314.             if (!String.Equals(fileName, Path.GetFileName(fileName)))
  315.                 throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "fileName");
  316.            
  317.             m_assemblyData.CheckResNameConflict(name);
  318.             m_assemblyData.CheckFileNameConflict(fileName);
  319.            
  320.             ResourceWriter resWriter;
  321.             string fullFileName;
  322.            
  323.             if (m_assemblyData.m_strDir == null) {
  324.                 // If assembly directory is null, use current directory
  325.                 fullFileName = Path.Combine(Environment.CurrentDirectory, fileName);
  326.                 resWriter = new ResourceWriter(fullFileName);
  327.             }
  328.             else {
  329.                 // Form the full path given the directory provided by user
  330.                 fullFileName = Path.Combine(m_assemblyData.m_strDir, fileName);
  331.                 resWriter = new ResourceWriter(fullFileName);
  332.             }
  333.             // get the full path
  334.             fullFileName = Path.GetFullPath(fullFileName);
  335.            
  336.             // retrieve just the file name
  337.             fileName = Path.GetFileName(fullFileName);
  338.            
  339.             m_assemblyData.AddResWriter(new ResWriterData(resWriter, null, name, fileName, fullFileName, attribute));
  340.             return resWriter;
  341.         }
  342.        
  343.        
  344. /**********************************************
  345.         *
  346.         * Add an existing resource file to the Assembly
  347.         *
  348.         **********************************************/       
  349.         [ResourceExposure(ResourceScope.Machine)]
  350.         [ResourceConsumption(ResourceScope.Machine)]
  351.         public void AddResourceFile(string name, string fileName)
  352.         {
  353.             AddResourceFile(name, fileName, ResourceAttributes.Public);
  354.         }
  355.        
  356. /**********************************************
  357.         *
  358.         * Add an existing resource file to the Assembly
  359.         *
  360.         **********************************************/       
  361.         [ResourceExposure(ResourceScope.Machine)]
  362.         [ResourceConsumption(ResourceScope.Machine)]
  363.         public void AddResourceFile(string name, string fileName, ResourceAttributes attribute)
  364.         {
  365.             CodeAccessPermission.DemandInternal(PermissionType.ReflectionEmit);
  366.             if (m_assemblyData.m_isSynchronized) {
  367.                 lock (m_assemblyData) {
  368.                     AddResourceFileNoLock(name, fileName, attribute);
  369.                 }
  370.             }
  371.             else {
  372.                 AddResourceFileNoLock(name, fileName, attribute);
  373.             }
  374.         }
  375.        
  376.         [ResourceExposure(ResourceScope.Machine)]
  377.         [ResourceConsumption(ResourceScope.Machine)]
  378.         private void AddResourceFileNoLock(string name, string fileName, ResourceAttributes attribute)
  379.         {
  380.             BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.AddResourceFile( " + name + ", " + fileName + ")");
  381.            
  382.             if (name == null)
  383.                 throw new ArgumentNullException("name");
  384.             if (name.Length == 0)
  385.                 throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), name);
  386.             if (fileName == null)
  387.                 throw new ArgumentNullException("fileName");
  388.             if (fileName.Length == 0)
  389.                 throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), fileName);
  390.             if (!String.Equals(fileName, Path.GetFileName(fileName)))
  391.                 throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "fileName");
  392.            
  393.             m_assemblyData.CheckResNameConflict(name);
  394.             m_assemblyData.CheckFileNameConflict(fileName);
  395.            
  396.             string fullFileName;
  397.            
  398.             if (m_assemblyData.m_strDir == null) {
  399.                 // If assembly directory is null, use current directory
  400.                 fullFileName = Path.Combine(Environment.CurrentDirectory, fileName);
  401.             }
  402.             else {
  403.                 // Form the full path given the directory provided by user
  404.                 fullFileName = Path.Combine(m_assemblyData.m_strDir, fileName);
  405.             }
  406.            
  407.             // get the full path
  408.             fullFileName = Path.GetFullPath(fullFileName);
  409.            
  410.             // retrieve just the file name
  411.             fileName = Path.GetFileName(fullFileName);
  412.            
  413.             if (File.Exists(fullFileName) == false)
  414.                 throw new FileNotFoundException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("IO.FileNotFound_FileName"), fileName), fileName);
  415.             m_assemblyData.AddResWriter(new ResWriterData(null, null, name, fileName, fullFileName, attribute));
  416.         }
  417.        
  418.         // Returns the names of all the resources
  419.         public override string[] GetManifestResourceNames()
  420.         {
  421.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
  422.         }
  423.        
  424.         public override FileStream GetFile(string name)
  425.         {
  426.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
  427.         }
  428.        
  429.         public override FileStream[] GetFiles(bool getResourceModules)
  430.         {
  431.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
  432.         }
  433.        
  434.         public override Stream GetManifestResourceStream(Type type, string name)
  435.         {
  436.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
  437.         }
  438.        
  439.         public override Stream GetManifestResourceStream(string name)
  440.         {
  441.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
  442.         }
  443.        
  444.         public override ManifestResourceInfo GetManifestResourceInfo(string resourceName)
  445.         {
  446.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
  447.         }
  448.        
  449.         public override string Location {
  450.             get {
  451.                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
  452.             }
  453.         }
  454.        
  455.         public override string ImageRuntimeVersion {
  456.             get { return RuntimeEnvironment.GetSystemVersion(); }
  457.         }
  458.        
  459.         public override string CodeBase {
  460.             get {
  461.                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
  462.             }
  463.         }
  464.        
  465.        
  466.        
  467.        
  468.        
  469. /**********************************************
  470.         *
  471.         * return a dynamic module with the specified name.
  472.         *
  473.         **********************************************/       
  474.         // the name of module for the look up
  475.         public ModuleBuilder GetDynamicModule(string name)
  476.         {
  477.             if (m_assemblyData.m_isSynchronized) {
  478.                 lock (m_assemblyData) {
  479.                     return GetDynamicModuleNoLock(name);
  480.                 }
  481.             }
  482.             else {
  483.                 return GetDynamicModuleNoLock(name);
  484.             }
  485.         }
  486.        
  487.         // the name of module for the look up
  488.         private ModuleBuilder GetDynamicModuleNoLock(string name)
  489.         {
  490.             BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.GetDynamicModule( " + name + " )");
  491.             if (name == null)
  492.                 throw new ArgumentNullException("name");
  493.             if (name.Length == 0)
  494.                 throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
  495.            
  496.             int size = m_assemblyData.m_moduleBuilderList.Count;
  497.             for (int i = 0; i < size; i++) {
  498.                 ModuleBuilder moduleBuilder = (ModuleBuilder)m_assemblyData.m_moduleBuilderList[i];
  499.                 if (moduleBuilder.m_moduleData.m_strModuleName.Equals(name)) {
  500.                     return moduleBuilder;
  501.                 }
  502.             }
  503.             return null;
  504.         }
  505.        
  506. /**********************************************
  507.         *
  508.         * Setting the entry point if the assembly builder is building
  509.         * an exe.
  510.         *
  511.         **********************************************/       
  512.         public void SetEntryPoint(MethodInfo entryMethod)
  513.         {
  514.             SetEntryPoint(entryMethod, PEFileKinds.ConsoleApplication);
  515.         }
  516.             // entry method for the assembly. We use this to determine the entry module
  517.         // file kind for the assembly.
  518.         public void SetEntryPoint(MethodInfo entryMethod, PEFileKinds fileKind)
  519.         {
  520.             CodeAccessPermission.DemandInternal(PermissionType.ReflectionEmit);
  521.             if (m_assemblyData.m_isSynchronized) {
  522.                 lock (m_assemblyData) {
  523.                     SetEntryPointNoLock(entryMethod, fileKind);
  524.                 }
  525.             }
  526.             else {
  527.                 SetEntryPointNoLock(entryMethod, fileKind);
  528.             }
  529.         }
  530.        
  531.             // entry method for the assembly. We use this to determine the entry module
  532.         // file kind for the assembly.
  533.         private void SetEntryPointNoLock(MethodInfo entryMethod, PEFileKinds fileKind)
  534.         {
  535.            
  536.             BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.SetEntryPoint");
  537.             if (entryMethod == null)
  538.                 throw new ArgumentNullException("entryMethod");
  539.            
  540.             //
  541.             //
  542.             Module tmpModule = entryMethod.Module;
  543.             if (!(tmpModule is ModuleBuilder && this.Equals(tmpModule.Assembly)))
  544.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EntryMethodNotDefinedInAssembly"));
  545.             m_assemblyData.m_entryPointModule = (ModuleBuilder)tmpModule;
  546.             m_assemblyData.m_entryPointMethod = entryMethod;
  547.             m_assemblyData.m_peFileKind = fileKind;
  548.             m_assemblyData.m_entryPointModule.SetEntryPoint(entryMethod);
  549.         }
  550.        
  551.        
  552.         // Override the EntryPoint method on Assembly.
  553.         public override MethodInfo EntryPoint {
  554.             get { return m_assemblyData.m_entryPointMethod; }
  555.         }
  556.        
  557. /**********************************************
  558.         * Use this function if client decides to form the custom attribute blob themselves
  559.         **********************************************/       
  560.         [System.Runtime.InteropServices.ComVisible(true)]
  561.         public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
  562.         {
  563.             CodeAccessPermission.DemandInternal(PermissionType.ReflectionEmit);
  564.             if (con == null)
  565.                 throw new ArgumentNullException("con");
  566.             if (binaryAttribute == null)
  567.                 throw new ArgumentNullException("binaryAttribute");
  568.            
  569.             ModuleBuilder inMemoryAssemblyModule;
  570.             inMemoryAssemblyModule = m_assemblyData.GetInMemoryAssemblyModule();
  571.                 // This is the AssemblyDef token
  572.                 // pass in the in-memory assembly module
  573.             TypeBuilder.InternalCreateCustomAttribute(AssemblyBuilderData.m_tkAssembly, inMemoryAssemblyModule.GetConstructorToken(con).Token, binaryAttribute, inMemoryAssemblyModule, false, typeof(System.Diagnostics.DebuggableAttribute) == con.DeclaringType);
  574.            
  575.             // Track the CA for persistence
  576.             if (m_assemblyData.m_access == AssemblyBuilderAccess.Run) {
  577.                 return;
  578.             }
  579.            
  580.             // tracking the CAs for persistence
  581.             m_assemblyData.AddCustomAttribute(con, binaryAttribute);
  582.         }
  583.        
  584. /**********************************************
  585.         * Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder
  586.         **********************************************/       
  587.         public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
  588.         {
  589.             CodeAccessPermission.DemandInternal(PermissionType.ReflectionEmit);
  590.             if (customBuilder == null) {
  591.                 throw new ArgumentNullException("customBuilder");
  592.             }
  593.            
  594.             ModuleBuilder inMemoryAssemblyModule;
  595.             inMemoryAssemblyModule = m_assemblyData.GetInMemoryAssemblyModule();
  596.             customBuilder.CreateCustomAttribute(inMemoryAssemblyModule, AssemblyBuilderData.m_tkAssembly);
  597.             // This is the AssemblyDef token
  598.             // Track the CA for persistence
  599.             if (m_assemblyData.m_access == AssemblyBuilderAccess.Run) {
  600.                 return;
  601.             }
  602.             m_assemblyData.AddCustomAttribute(customBuilder);
  603.         }
  604.        
  605.        
  606. /**********************************************
  607.         *
  608.         * Saves the assembly to disk. Also saves all dynamic modules defined
  609.         * in this dynamic assembly. Assembly file name can be the same as one of
  610.         * the module's name. If so, assembly info is stored within that module.
  611.         * Assembly file name can be different from all of the modules underneath. In
  612.         * this case, assembly is stored stand alone.
  613.         *
  614.         **********************************************/       
  615.        
  616.         [ResourceExposure(ResourceScope.Machine)]
  617.         [ResourceConsumption(ResourceScope.Machine)]
  618.         // assembly file name
  619.         public void Save(string assemblyFileName)
  620.         {
  621.             Save(assemblyFileName, System.Reflection.PortableExecutableKinds.ILOnly, System.Reflection.ImageFileMachine.I386);
  622.         }
  623.        
  624.         [ResourceExposure(ResourceScope.Machine)]
  625.         [ResourceConsumption(ResourceScope.Machine)]
  626.         public void Save(string assemblyFileName, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
  627.         {
  628.             if (m_assemblyData.m_isSynchronized) {
  629.                 lock (m_assemblyData) {
  630.                     SaveNoLock(assemblyFileName, portableExecutableKind, imageFileMachine);
  631.                 }
  632.             }
  633.             else {
  634.                 SaveNoLock(assemblyFileName, portableExecutableKind, imageFileMachine);
  635.             }
  636.         }
  637.        
  638.         [ResourceExposure(ResourceScope.Machine)]
  639.         [ResourceConsumption(ResourceScope.Machine)]
  640.         private void SaveNoLock(string assemblyFileName, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
  641.         {
  642.             int i;
  643.             int size;
  644.             Type type;
  645.             TypeBuilder typeBuilder;
  646.             ModuleBuilder modBuilder;
  647.             string strModFileName;
  648.             ModuleBuilder assemblyModule;
  649.             ResWriterData tempRes;
  650.             int[] tkAttrs = null;
  651.             int[] tkAttrs2 = null;
  652.             ModuleBuilder onDiskAssemblyModule;
  653.            
  654.             BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.Save( " + assemblyFileName + " )");
  655.            
  656.             string tmpVersionFile = null;
  657.            
  658.             try {
  659.                 if (m_assemblyData.m_iCABuilder != 0)
  660.                     tkAttrs = new int[m_assemblyData.m_iCABuilder];
  661.                 if (m_assemblyData.m_iCAs != 0)
  662.                     tkAttrs2 = new int[m_assemblyData.m_iCAs];
  663.                
  664.                 if (m_assemblyData.m_isSaved == true) {
  665.                     // assembly has been saved before!
  666.                     throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, Environment.GetResourceString(ResId.InvalidOperation_AssemblyHasBeenSaved), nGetSimpleName()));
  667.                 }
  668.                
  669.                 if ((m_assemblyData.m_access & AssemblyBuilderAccess.Save) != AssemblyBuilderAccess.Save) {
  670.                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CantSaveTransientAssembly"));
  671.                 }
  672.                
  673.                 if (assemblyFileName == null)
  674.                     throw new ArgumentNullException("assemblyFileName");
  675.                 if (assemblyFileName.Length == 0)
  676.                     throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "assemblyFileName");
  677.                 if (!String.Equals(assemblyFileName, Path.GetFileName(assemblyFileName)))
  678.                     throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "assemblyFileName");
  679.                
  680.                 // Check if assembly info is supposed to be stored with one of the module files.
  681.                 assemblyModule = m_assemblyData.FindModuleWithFileName(assemblyFileName);
  682.                
  683.                 if (assemblyModule != null) {
  684.             &