2 // System.Reflection.Emit/AssemblyBuilder.cs
5 // Paolo Molaro (lupus@ximian.com)
7 // (C) 2001 Ximian, Inc. http://www.ximian.com
11 using System.Reflection;
12 using System.Resources;
14 using System.Security.Policy;
15 using System.Runtime.Serialization;
16 using System.Globalization;
17 using System.Runtime.CompilerServices;
18 using System.Collections;
20 namespace System.Reflection.Emit {
22 internal struct MonoResource {
25 public string filename;
26 public ResourceAttributes attrs;
29 public sealed class AssemblyBuilder : Assembly {
30 private IntPtr dynamic_assembly;
31 private MethodInfo entry_point;
32 private ModuleBuilder[] modules;
35 private CustomAttributeBuilder[] cattrs;
36 private MonoResource[] resources;
42 PEFileKinds pekind = PEFileKinds.Dll;
44 internal Type corlib_object_type = typeof (System.Object);
45 internal Type corlib_value_type = typeof (System.ValueType);
46 internal Type corlib_enum_type = typeof (System.Enum);
47 private int[] table_indexes;
48 internal ArrayList methods;
49 Hashtable us_string_cache = new Hashtable ();
51 [MethodImplAttribute(MethodImplOptions.InternalCall)]
52 private static extern void basic_init (AssemblyBuilder ab);
54 internal AssemblyBuilder (AssemblyName n, string directory, AssemblyBuilderAccess access) {
60 internal int get_next_table_index (object obj, int table, bool inc) {
61 if (table_indexes == null) {
62 table_indexes = new int [64];
63 for (int i=0; i < 64; ++i)
64 table_indexes [i] = 1;
65 /* allow room for .<Module> in TypeDef table */
66 table_indexes [0x02] = 2;
68 // Console.WriteLine ("getindex for table "+table.ToString()+" got "+table_indexes [table].ToString());
70 if ((table == 0x06) && (methods != null))
72 return table_indexes [table]++;
74 return table_indexes [table];
77 public override string CodeBase {
83 public override MethodInfo EntryPoint {
89 public override string Location {
95 public void AddResourceFile (string name, string fileName)
97 AddResourceFile (name, fileName, ResourceAttributes.Public);
100 public void AddResourceFile (string name, string fileName, ResourceAttributes attribute)
102 if (resources != null) {
103 MonoResource[] new_r = new MonoResource [resources.Length + 1];
104 System.Array.Copy(resources, new_r, resources.Length);
107 resources = new MonoResource [1];
109 int p = resources.Length - 1;
110 resources [p].name = name;
111 resources [p].filename = fileName;
112 resources [p].attrs = attribute;
115 public void EmbedResourceFile (string name, string fileName)
117 EmbedResourceFile (name, fileName, ResourceAttributes.Public);
120 public void EmbedResourceFile (string name, string fileName, ResourceAttributes attribute)
122 if (resources != null) {
123 MonoResource[] new_r = new MonoResource [resources.Length + 1];
124 System.Array.Copy(resources, new_r, resources.Length);
127 resources = new MonoResource [1];
129 int p = resources.Length - 1;
130 resources [p].name = name;
131 resources [p].attrs = attribute;
133 FileStream s = new FileStream (fileName, FileMode.Open, FileAccess.Read);
135 resources [p].data = new byte [len];
136 s.Read (resources [p].data, 0, (int)len);
143 internal void EmbedResource (string name, byte[] blob, ResourceAttributes attribute)
145 if (resources != null) {
146 MonoResource[] new_r = new MonoResource [resources.Length + 1];
147 System.Array.Copy(resources, new_r, resources.Length);
150 resources = new MonoResource [1];
152 int p = resources.Length - 1;
153 resources [p].name = name;
154 resources [p].attrs = attribute;
155 resources [p].data = blob;
158 public ModuleBuilder DefineDynamicModule (string name)
160 return DefineDynamicModule (name, name, false);
163 public ModuleBuilder DefineDynamicModule (string name, bool emitSymbolInfo)
165 return DefineDynamicModule (name, name, emitSymbolInfo);
168 public ModuleBuilder DefineDynamicModule(string name, string fileName)
170 return DefineDynamicModule (name, fileName, false);
173 public ModuleBuilder DefineDynamicModule (string name, string fileName,
176 ModuleBuilder r = new ModuleBuilder (this, name, fileName, emitSymbolInfo, modules == null);
178 if (modules != null) {
179 ModuleBuilder[] new_modules = new ModuleBuilder [modules.Length + 1];
180 System.Array.Copy(modules, new_modules, modules.Length);
181 new_modules [modules.Length] = r;
182 modules = new_modules;
184 modules = new ModuleBuilder [1];
190 public IResourceWriter DefineResource (string name, string description, string fileName)
192 return DefineResource (name, description, fileName, ResourceAttributes.Public);
195 public IResourceWriter DefineResource (string name, string description,
196 string fileName, ResourceAttributes attribute)
201 public void DefineUnmanagedResource (byte[] resource)
205 public void DefineUnmanagedResource (string resourceFileName)
209 public void DefineVersionInfoResource ()
213 public void DefineVersionInfoResource (string product, string productVersion,
214 string company, string copyright, string trademark)
218 public ModuleBuilder GetDynamicModule (string name)
223 public override Type[] GetExportedTypes ()
228 public override FileStream GetFile (string name)
233 /*public virtual FileStream[] GetFiles() {
236 public override FileStream[] GetFiles(bool getResourceModules) {
240 /*public virtual ManifestResourceInfo GetManifestResourceInfo(string resourceName)
244 public virtual string[] GetManifestResourceNames() {
247 public virtual Stream GetManifestResourceStream(string name) {
250 public virtual Stream GetManifestResourceStream(Type type, string name) {
254 [MethodImplAttribute(MethodImplOptions.InternalCall)]
255 private static extern int getUSIndex (AssemblyBuilder ab, string str);
257 [MethodImplAttribute(MethodImplOptions.InternalCall)]
258 private static extern int getToken (AssemblyBuilder ab, object obj);
260 internal int GetToken (string str) {
261 if (us_string_cache.Contains (str))
262 return (int)us_string_cache [str];
263 int result = getUSIndex (this, str);
264 us_string_cache [str] = result;
268 internal int GetToken (MemberInfo member) {
269 return getToken (this, member);
272 internal int GetToken (SignatureHelper helper) {
273 return getToken (this, helper);
276 [MethodImplAttribute(MethodImplOptions.InternalCall)]
277 private static extern int getDataChunk (AssemblyBuilder ab, byte[] buf, int offset);
279 public void Save (string assemblyFileName)
281 byte[] buf = new byte [65536];
285 build_metadata (this);
287 foreach (ModuleBuilder module in modules)
291 assemblyFileName = String.Format ("{0}{1}{2}", dir, System.IO.Path.DirectorySeparatorChar, assemblyFileName);
294 file = new FileStream (assemblyFileName, FileMode.Create, FileAccess.Write);
297 while ((count = getDataChunk (this, buf, offset)) != 0) {
298 file.Write (buf, 0, count);
304 // The constant 0x80000000 is internal to Mono, it means `make executable'
306 File.SetAttributes (assemblyFileName, (FileAttributes) (unchecked ((int) 0x80000000)));
309 [MethodImplAttribute(MethodImplOptions.InternalCall)]
310 private static extern void build_metadata (AssemblyBuilder ab);
312 public void SetEntryPoint (MethodInfo entryMethod)
314 SetEntryPoint (entryMethod, PEFileKinds.ConsoleApplication);
317 public void SetEntryPoint (MethodInfo entryMethod, PEFileKinds fileKind)
319 entry_point = entryMethod;
323 public void SetCustomAttribute( CustomAttributeBuilder customBuilder) {
324 string attrname = customBuilder.Ctor.ReflectedType.FullName;
327 if (attrname == "System.Reflection.AssemblyVersionAttribute") {
328 data = customBuilder.Data;
330 len = CustomAttributeBuilder.decode_len (data, pos, out pos);
331 version = CustomAttributeBuilder.string_from_bytes (data, pos, len);
333 } else if (attrname == "System.Reflection.AssemblyKeyFileAttribute") {
334 data = customBuilder.Data;
336 len = CustomAttributeBuilder.decode_len (data, pos, out pos);
337 keyfile = CustomAttributeBuilder.string_from_bytes (data, pos, len);
338 } else if (attrname == "System.Reflection.AssemblyCultureAttribute") {
339 data = customBuilder.Data;
341 len = CustomAttributeBuilder.decode_len (data, pos, out pos);
342 culture = CustomAttributeBuilder.string_from_bytes (data, pos, len);
343 } else if (attrname == "System.Reflection.AssemblyAlgorithmIdAttribute") {
344 data = customBuilder.Data;
346 algid = (uint)data [pos];
347 algid |= ((uint)data [pos + 1]) << 8;
348 algid |= ((uint)data [pos + 2]) << 16;
349 algid |= ((uint)data [pos + 3]) << 24;
350 } else if (attrname == "System.Reflection.AssemblyFlagsAttribute") {
351 data = customBuilder.Data;
353 flags = (uint)data [pos];
354 flags |= ((uint)data [pos + 1]) << 8;
355 flags |= ((uint)data [pos + 2]) << 16;
356 flags |= ((uint)data [pos + 3]) << 24;
358 } else if (attrname == "System.Reflection.AssemblyDelaySignAttribute") {
359 data = customBuilder.Data;
361 delay_sign = data [2] != 0;
363 if (cattrs != null) {
364 CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1];
365 cattrs.CopyTo (new_array, 0);
366 new_array [cattrs.Length] = customBuilder;
369 cattrs = new CustomAttributeBuilder [1];
370 cattrs [0] = customBuilder;
373 public void SetCustomAttribute( ConstructorInfo con, byte[] binaryAttribute) {
374 SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
377 public void SetCorlibTypeBuilders (Type corlib_object_type, Type corlib_value_type, Type corlib_enum_type) {
378 this.corlib_object_type = corlib_object_type;
379 this.corlib_value_type = corlib_value_type;
380 this.corlib_enum_type = corlib_enum_type;