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 public ModuleBuilder DefineDynamicModule (string name)
145 return DefineDynamicModule (name, name, false);
148 public ModuleBuilder DefineDynamicModule (string name, bool emitSymbolInfo)
150 return DefineDynamicModule (name, name, emitSymbolInfo);
153 public ModuleBuilder DefineDynamicModule(string name, string fileName)
155 return DefineDynamicModule (name, fileName, false);
158 public ModuleBuilder DefineDynamicModule (string name, string fileName,
161 ModuleBuilder r = new ModuleBuilder (this, name, fileName, emitSymbolInfo);
163 if (modules != null) {
164 ModuleBuilder[] new_modules = new ModuleBuilder [modules.Length + 1];
165 System.Array.Copy(modules, new_modules, modules.Length);
166 new_modules [modules.Length] = r;
167 modules = new_modules;
169 modules = new ModuleBuilder [1];
175 public IResourceWriter DefineResource (string name, string description, string fileName)
177 return DefineResource (name, description, fileName, ResourceAttributes.Public);
180 public IResourceWriter DefineResource (string name, string description,
181 string fileName, ResourceAttributes attribute)
186 public void DefineUnmanagedResource (byte[] resource)
190 public void DefineUnmanagedResource (string resourceFileName)
194 public void DefineVersionInfoResource ()
198 public void DefineVersionInfoResource (string product, string productVersion,
199 string company, string copyright, string trademark)
203 public ModuleBuilder GetDynamicModule (string name)
208 public override Type[] GetExportedTypes ()
213 public override FileStream GetFile (string name)
218 /*public virtual FileStream[] GetFiles() {
221 public override FileStream[] GetFiles(bool getResourceModules) {
225 /*public virtual ManifestResourceInfo GetManifestResourceInfo(string resourceName)
229 public virtual string[] GetManifestResourceNames() {
232 public virtual Stream GetManifestResourceStream(string name) {
235 public virtual Stream GetManifestResourceStream(Type type, string name) {
239 [MethodImplAttribute(MethodImplOptions.InternalCall)]
240 private static extern int getUSIndex (AssemblyBuilder ab, string str);
242 [MethodImplAttribute(MethodImplOptions.InternalCall)]
243 private static extern int getToken (AssemblyBuilder ab, MemberInfo member);
245 internal int GetToken (string str) {
246 if (us_string_cache.Contains (str))
247 return (int)us_string_cache [str];
248 int result = getUSIndex (this, str);
249 us_string_cache [str] = result;
253 internal int GetToken (MemberInfo member) {
254 return getToken (this, member);
257 [MethodImplAttribute(MethodImplOptions.InternalCall)]
258 private static extern int getDataChunk (AssemblyBuilder ab, byte[] buf, int offset);
260 public void Save (string assemblyFileName)
262 byte[] buf = new byte [65536];
267 assemblyFileName = String.Format ("{0}{1}{2}", dir, System.IO.Path.DirectorySeparatorChar, assemblyFileName);
270 file = new FileStream (assemblyFileName, FileMode.Create, FileAccess.Write);
273 while ((count = getDataChunk (this, buf, offset)) != 0) {
274 file.Write (buf, 0, count);
280 // The constant 0x80000000 is internal to Mono, it means `make executable'
282 File.SetAttributes (assemblyFileName, (FileAttributes) 0x80000000);
285 public void SetEntryPoint (MethodInfo entryMethod)
287 SetEntryPoint (entryMethod, PEFileKinds.ConsoleApplication);
290 public void SetEntryPoint (MethodInfo entryMethod, PEFileKinds fileKind)
292 entry_point = entryMethod;
296 public void SetCustomAttribute( CustomAttributeBuilder customBuilder) {
297 string attrname = customBuilder.Ctor.ReflectedType.FullName;
300 if (attrname == "System.Reflection.AssemblyVersionAttribute") {
301 data = customBuilder.Data;
303 len = CustomAttributeBuilder.decode_len (data, pos, out pos);
304 version = CustomAttributeBuilder.string_from_bytes (data, pos, len);
306 } else if (attrname == "System.Reflection.AssemblyKeyFileAttribute") {
307 data = customBuilder.Data;
309 len = CustomAttributeBuilder.decode_len (data, pos, out pos);
310 keyfile = CustomAttributeBuilder.string_from_bytes (data, pos, len);
311 } else if (attrname == "System.Reflection.AssemblyCultureAttribute") {
312 data = customBuilder.Data;
314 len = CustomAttributeBuilder.decode_len (data, pos, out pos);
315 culture = CustomAttributeBuilder.string_from_bytes (data, pos, len);
316 } else if (attrname == "System.Reflection.AssemblyAlgorithmIdAttribute") {
317 data = customBuilder.Data;
319 algid = (uint)data [pos];
320 algid |= ((uint)data [pos + 1]) << 8;
321 algid |= ((uint)data [pos + 2]) << 16;
322 algid |= ((uint)data [pos + 3]) << 24;
323 } else if (attrname == "System.Reflection.AssemblyFlagsAttribute") {
324 data = customBuilder.Data;
326 flags = (uint)data [pos];
327 flags |= ((uint)data [pos + 1]) << 8;
328 flags |= ((uint)data [pos + 2]) << 16;
329 flags |= ((uint)data [pos + 3]) << 24;
331 } else if (attrname == "System.Reflection.AssemblyDelaySignAttribute") {
332 data = customBuilder.Data;
334 delay_sign = data [2] != 0;
336 if (cattrs != null) {
337 CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1];
338 cattrs.CopyTo (new_array, 0);
339 new_array [cattrs.Length] = customBuilder;
342 cattrs = new CustomAttributeBuilder [1];
343 cattrs [0] = customBuilder;
346 public void SetCustomAttribute( ConstructorInfo con, byte[] binaryAttribute) {
347 SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
350 public void SetCorlibTypeBuilders (Type corlib_object_type, Type corlib_value_type, Type corlib_enum_type) {
351 this.corlib_object_type = corlib_object_type;
352 this.corlib_value_type = corlib_value_type;
353 this.corlib_enum_type = corlib_enum_type;