PageRenderTime 59ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 0ms

/Microsoft.Scripting.Core/Compiler/AssemblyGen.cs

https://bitbucket.org/stefanrusek/xronos
C# | 184 lines | 130 code | 29 blank | 25 comment | 9 complexity | 101e905ee8f3b2370e3088723b4f87c4 MD5 | raw file
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Microsoft Public License. A
  6. * copy of the license can be found in the License.html file at the root of this distribution. If
  7. * you cannot locate the Microsoft Public License, please send an email to
  8. * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. * by the terms of the Microsoft Public License.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. using System; using Microsoft;
  16. using System.Collections.Generic;
  17. #if CODEPLEX_40
  18. using System.Dynamic.Utils;
  19. #else
  20. using Microsoft.Scripting.Utils;
  21. #endif
  22. using System.IO;
  23. using System.Reflection;
  24. using System.Reflection.Emit;
  25. using System.Security;
  26. using System.Text;
  27. using System.Threading;
  28. #if CODEPLEX_40
  29. namespace System.Linq.Expressions.Compiler {
  30. #else
  31. namespace Microsoft.Linq.Expressions.Compiler {
  32. #endif
  33. internal sealed class AssemblyGen {
  34. private static AssemblyGen _assembly;
  35. // Testing options. Only ever set in MICROSOFT_SCRIPTING_CORE build
  36. // configurations, see SetSaveAssemblies
  37. #if MICROSOFT_SCRIPTING_CORE
  38. private static string _saveAssembliesPath;
  39. private static bool _saveAssemblies;
  40. #endif
  41. private readonly AssemblyBuilder _myAssembly;
  42. private readonly ModuleBuilder _myModule;
  43. #if MICROSOFT_SCRIPTING_CORE && !SILVERLIGHT
  44. private readonly string _outFileName; // can be null iff !SaveAndReloadAssemblies
  45. private readonly string _outDir; // null means the current directory
  46. #endif
  47. private int _index;
  48. private static AssemblyGen Assembly {
  49. get {
  50. if (_assembly == null) {
  51. Interlocked.CompareExchange(ref _assembly, new AssemblyGen(), null);
  52. }
  53. return _assembly;
  54. }
  55. }
  56. private AssemblyGen() {
  57. var name = new AssemblyName("Snippets");
  58. #if SILVERLIGHT // AssemblyBuilderAccess.RunAndSave, Environment.CurrentDirectory
  59. _myAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
  60. _myModule = _myAssembly.DefineDynamicModule(name.Name, false);
  61. #else
  62. // mark the assembly transparent so that it works in partial trust:
  63. var attributes = new[] {
  64. new CustomAttributeBuilder(typeof(SecurityTransparentAttribute).GetConstructor(Type.EmptyTypes), new object[0])
  65. };
  66. #if MICROSOFT_SCRIPTING_CORE
  67. if (_saveAssemblies) {
  68. string outDir = _saveAssembliesPath ?? Directory.GetCurrentDirectory();
  69. try {
  70. outDir = Path.GetFullPath(outDir);
  71. } catch (Exception) {
  72. throw Error.InvalidOutputDir();
  73. }
  74. try {
  75. Path.Combine(outDir, name.Name + ".dll");
  76. } catch (ArgumentException) {
  77. throw Error.InvalidAsmNameOrExtension();
  78. }
  79. _outFileName = name.Name + ".dll";
  80. _outDir = outDir;
  81. _myAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave, outDir,
  82. null, null, null, null, false, attributes);
  83. _myModule = _myAssembly.DefineDynamicModule(name.Name, _outFileName, false);
  84. } else
  85. #endif
  86. {
  87. _myAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run, attributes);
  88. _myModule = _myAssembly.DefineDynamicModule(name.Name, false);
  89. }
  90. _myAssembly.DefineVersionInfoResource();
  91. #endif
  92. }
  93. private TypeBuilder DefineType(string name, Type parent, TypeAttributes attr) {
  94. ContractUtils.RequiresNotNull(name, "name");
  95. ContractUtils.RequiresNotNull(parent, "parent");
  96. StringBuilder sb = new StringBuilder(name);
  97. int index = Interlocked.Increment(ref _index);
  98. sb.Append("$");
  99. sb.Append(index);
  100. // There is a bug in Reflection.Emit that leads to
  101. // Unhandled Exception: System.Runtime.InteropServices.COMException (0x80131130): Record not found on lookup.
  102. // if there is any of the characters []*&+,\ in the type name and a method defined on the type is called.
  103. sb.Replace('+', '_').Replace('[', '_').Replace(']', '_').Replace('*', '_').Replace('&', '_').Replace(',', '_').Replace('\\', '_');
  104. name = sb.ToString();
  105. return _myModule.DefineType(name, attr, parent);
  106. }
  107. internal static TypeBuilder DefineDelegateType(string name) {
  108. return Assembly.DefineType(
  109. name,
  110. typeof(MulticastDelegate),
  111. TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.AnsiClass | TypeAttributes.AutoClass
  112. );
  113. }
  114. #if MICROSOFT_SCRIPTING_CORE
  115. //Return the location of the saved assembly file.
  116. //The file location is used by PE verification in Microsoft.Scripting.
  117. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  118. internal string SaveAssembly() {
  119. #if !SILVERLIGHT // AssemblyBuilder.Save
  120. _myAssembly.Save(_outFileName, PortableExecutableKinds.ILOnly, ImageFileMachine.I386);
  121. return Path.Combine(_outDir, _outFileName);
  122. #else
  123. return null;
  124. #endif
  125. }
  126. // NOTE: this method is called through reflection from Microsoft.Scripting
  127. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  128. internal static void SetSaveAssemblies(bool enable, string directory) {
  129. _saveAssemblies = enable;
  130. _saveAssembliesPath = directory;
  131. }
  132. // NOTE: this method is called through reflection from Microsoft.Scripting
  133. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  134. internal static string[] SaveAssembliesToDisk() {
  135. if (!_saveAssemblies) {
  136. return new string[0];
  137. }
  138. var assemlyLocations = new List<string>();
  139. // first save all assemblies to disk:
  140. if (_assembly != null) {
  141. string assemblyLocation = _assembly.SaveAssembly();
  142. if (assemblyLocation != null) {
  143. assemlyLocations.Add(assemblyLocation);
  144. }
  145. _assembly = null;
  146. }
  147. return assemlyLocations.ToArray();
  148. }
  149. #endif
  150. }
  151. internal static class SymbolGuids {
  152. internal static readonly Guid DocumentType_Text =
  153. new Guid(0x5a869d0b, 0x6611, 0x11d3, 0xbd, 0x2a, 0, 0, 0xf8, 8, 0x49, 0xbd);
  154. }
  155. }