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 Hashtable us_string_cache = new Hashtable ();
50 [MethodImplAttribute(MethodImplOptions.InternalCall)]
51 private static extern void basic_init (AssemblyBuilder ab);
53 internal AssemblyBuilder (AssemblyName n, string directory, AssemblyBuilderAccess access) {
59 internal int get_next_table_index (object obj, int table, bool inc) {
60 if (table_indexes == null) {
61 table_indexes = new int [64];
62 for (int i=0; i < 64; ++i)
63 table_indexes [i] = 1;
64 /* allow room for .<Module> in TypeDef table */
65 table_indexes [0x02] = 2;
67 // Console.WriteLine ("getindex for table "+table.ToString()+" got "+table_indexes [table].ToString());
69 return table_indexes [table]++;
70 return table_indexes [table];
73 public override string CodeBase {
79 public override MethodInfo EntryPoint {
85 public override string Location {
91 public void AddResourceFile (string name, string fileName)
93 AddResourceFile (name, fileName, ResourceAttributes.Public);
96 public void AddResourceFile (string name, string fileName, ResourceAttributes attribute)
98 if (resources != null) {
99 MonoResource[] new_r = new MonoResource [resources.Length + 1];
100 System.Array.Copy(resources, new_r, resources.Length);
103 resources = new MonoResource [1];
105 int p = resources.Length - 1;
106 resources [p].name = name;
107 resources [p].filename = fileName;
108 resources [p].attrs = attribute;
111 public void EmbedResourceFile (string name, string fileName)
113 EmbedResourceFile (name, fileName, ResourceAttributes.Public);
116 public void EmbedResourceFile (string name, string fileName, ResourceAttributes attribute)
118 if (resources != null) {
119 MonoResource[] new_r = new MonoResource [resources.Length + 1];
120 System.Array.Copy(resources, new_r, resources.Length);
123 resources = new MonoResource [1];
125 int p = resources.Length - 1;
126 resources [p].name = name;
127 resources [p].attrs = attribute;
129 FileStream s = new FileStream (fileName, FileMode.Open, FileAccess.Read);
131 resources [p].data = new byte [len];
132 s.Read (resources [p].data, 0, (int)len);
139 internal void EmbedResource (string name, byte[] blob, ResourceAttributes attribute)
141 if (resources != null) {
142 MonoResource[] new_r = new MonoResource [resources.Length + 1];
143 System.Array.Copy(resources, new_r, resources.Length);
146 resources = new MonoResource [1];
148 int p = resources.Length - 1;
149 resources [p].name = name;
150 resources [p].attrs = attribute;
151 resources [p].data = blob;
154 public ModuleBuilder DefineDynamicModule (string name)
156 return DefineDynamicModule (name, name, false);
159 public ModuleBuilder DefineDynamicModule (string name, bool emitSymbolInfo)
161 return DefineDynamicModule (name, name, emitSymbolInfo);
164 public ModuleBuilder DefineDynamicModule(string name, string fileName)
166 return DefineDynamicModule (name, fileName, false);
169 public ModuleBuilder DefineDynamicModule (string name, string fileName,
172 ModuleBuilder r = new ModuleBuilder (this, name, fileName, emitSymbolInfo, modules == null);
174 if (modules != null) {
175 ModuleBuilder[] new_modules = new ModuleBuilder [modules.Length + 1];
176 System.Array.Copy(modules, new_modules, modules.Length);
177 new_modules [modules.Length] = r;
178 modules = new_modules;
180 modules = new ModuleBuilder [1];
186 public IResourceWriter DefineResource (string name, string description, string fileName)
188 return DefineResource (name, description, fileName, ResourceAttributes.Public);
191 public IResourceWriter DefineResource (string name, string description,
192 string fileName, ResourceAttributes attribute)
197 public void DefineUnmanagedResource (byte[] resource)
201 public void DefineUnmanagedResource (string resourceFileName)
205 public void DefineVersionInfoResource ()
209 public void DefineVersionInfoResource (string product, string productVersion,
210 string company, string copyright, string trademark)
214 public ModuleBuilder GetDynamicModule (string name)
219 public override Type[] GetExportedTypes ()
224 public override FileStream GetFile (string name)
229 /*public virtual FileStream[] GetFiles() {
232 public override FileStream[] GetFiles(bool getResourceModules) {
236 /*public virtual ManifestResourceInfo GetManifestResourceInfo(string resourceName)
240 public virtual string[] GetManifestResourceNames() {
243 public virtual Stream GetManifestResourceStream(string name) {
246 public virtual Stream GetManifestResourceStream(Type type, string name) {
250 [MethodImplAttribute(MethodImplOptions.InternalCall)]
251 private static extern int getUSIndex (AssemblyBuilder ab, string str);
253 [MethodImplAttribute(MethodImplOptions.InternalCall)]
254 private static extern int getToken (AssemblyBuilder ab, object obj);
256 internal int GetToken (string str) {
257 if (us_string_cache.Contains (str))
258 return (int)us_string_cache [str];
259 int result = getUSIndex (this, str);
260 us_string_cache [str] = result;
264 internal int GetToken (MemberInfo member) {
265 return getToken (this, member);
268 internal int GetToken (SignatureHelper helper) {
269 return getToken (this, helper);
272 [MethodImplAttribute(MethodImplOptions.InternalCall)]
273 private static extern int getDataChunk (AssemblyBuilder ab, byte[] buf, int offset);
275 public void Save (string assemblyFileName)
277 byte[] buf = new byte [65536];
281 build_metadata (this);
283 foreach (ModuleBuilder module in modules)
287 assemblyFileName = String.Format ("{0}{1}{2}", dir, System.IO.Path.DirectorySeparatorChar, assemblyFileName);
290 file = new FileStream (assemblyFileName, FileMode.Create, FileAccess.Write);
293 while ((count = getDataChunk (this, buf, offset)) != 0) {
294 file.Write (buf, 0, count);
300 // The constant 0x80000000 is internal to Mono, it means `make executable'
302 File.SetAttributes (assemblyFileName, (FileAttributes) (unchecked ((int) 0x80000000)));
305 [MethodImplAttribute(MethodImplOptions.InternalCall)]
306 private static extern void build_metadata (AssemblyBuilder ab);
308 public void SetEntryPoint (MethodInfo entryMethod)
310 SetEntryPoint (entryMethod, PEFileKinds.ConsoleApplication);
313 public void SetEntryPoint (MethodInfo entryMethod, PEFileKinds fileKind)
315 entry_point = entryMethod;
319 public void SetCustomAttribute( CustomAttributeBuilder customBuilder) {
320 string attrname = customBuilder.Ctor.ReflectedType.FullName;
323 if (attrname == "System.Reflection.AssemblyVersionAttribute") {
324 data = customBuilder.Data;
326 len = CustomAttributeBuilder.decode_len (data, pos, out pos);
327 version = CustomAttributeBuilder.string_from_bytes (data, pos, len);
329 } else if (attrname == "System.Reflection.AssemblyKeyFileAttribute") {
330 data = customBuilder.Data;
332 len = CustomAttributeBuilder.decode_len (data, pos, out pos);
333 keyfile = CustomAttributeBuilder.string_from_bytes (data, pos, len);
334 } else if (attrname == "System.Reflection.AssemblyCultureAttribute") {
335 data = customBuilder.Data;
337 len = CustomAttributeBuilder.decode_len (data, pos, out pos);
338 culture = CustomAttributeBuilder.string_from_bytes (data, pos, len);
339 } else if (attrname == "System.Reflection.AssemblyAlgorithmIdAttribute") {
340 data = customBuilder.Data;
342 algid = (uint)data [pos];
343 algid |= ((uint)data [pos + 1]) << 8;
344 algid |= ((uint)data [pos + 2]) << 16;
345 algid |= ((uint)data [pos + 3]) << 24;
346 } else if (attrname == "System.Reflection.AssemblyFlagsAttribute") {
347 data = customBuilder.Data;
349 flags = (uint)data [pos];
350 flags |= ((uint)data [pos + 1]) << 8;
351 flags |= ((uint)data [pos + 2]) << 16;
352 flags |= ((uint)data [pos + 3]) << 24;
354 } else if (attrname == "System.Reflection.AssemblyDelaySignAttribute") {
355 data = customBuilder.Data;
357 delay_sign = data [2] != 0;
359 if (cattrs != null) {
360 CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1];
361 cattrs.CopyTo (new_array, 0);
362 new_array [cattrs.Length] = customBuilder;
365 cattrs = new CustomAttributeBuilder [1];
366 cattrs [0] = customBuilder;
369 public void SetCustomAttribute( ConstructorInfo con, byte[] binaryAttribute) {
370 SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
373 public void SetCorlibTypeBuilders (Type corlib_object_type, Type corlib_value_type, Type corlib_enum_type) {
374 this.corlib_object_type = corlib_object_type;
375 this.corlib_value_type = corlib_value_type;
376 this.corlib_enum_type = corlib_enum_type;