3 // System.Reflection.Emit/ModuleBuilder.cs
6 // Paolo Molaro (lupus@ximian.com)
8 // (C) 2001 Ximian, Inc. http://www.ximian.com
12 using System.Reflection;
13 using System.Collections;
14 using System.Runtime.CompilerServices;
15 using System.Runtime.InteropServices;
16 using System.Diagnostics.SymbolStore;
19 namespace System.Reflection.Emit {
20 public class ModuleBuilder : Module {
21 private TypeBuilder[] types;
22 private CustomAttributeBuilder[] cattrs;
24 private int table_idx;
25 internal AssemblyBuilder assemblyb;
26 private ISymbolWriter symbol_writer;
27 private MethodInfo symwriter_define_local;
30 internal ModuleBuilder (AssemblyBuilder assb, string name, string fullyqname, bool emitSymbolInfo) {
31 this.name = this.scopename = name;
32 this.fqname = fullyqname;
33 this.assembly = this.assemblyb = assb;
34 guid = Guid.NewGuid().ToByteArray ();
35 table_idx = get_next_table_index (this, 0x00, true);
36 name_cache = new Hashtable ();
39 GetSymbolWriter (fullyqname);
42 internal void GetSymbolWriter (string filename)
46 assembly = Assembly.Load ("Mono.CSharp.Debugger");
47 } catch (FileNotFoundException) {
51 Type type = assembly.GetType ("Mono.CSharp.Debugger.MonoSymbolWriter");
55 if (assemblyb.methods == null)
56 assemblyb.methods = new ArrayList ();
58 // First get the constructor.
60 Type[] arg_types = new Type [3];
61 arg_types [0] = typeof (ModuleBuilder);
62 arg_types [1] = typeof (string);
63 arg_types [2] = typeof (ArrayList);
64 ConstructorInfo constructor = type.GetConstructor (arg_types);
66 object[] args = new object [3];
69 args [2] = assemblyb.methods;
71 if (constructor == null)
74 Object instance = constructor.Invoke (args);
78 if (!(instance is ISymbolWriter))
81 symbol_writer = (ISymbolWriter) instance;
84 // Get the DefineLocalVariable method.
86 Type[] arg_types = new Type [6];
87 arg_types [0] = typeof (string);
88 arg_types [1] = typeof (LocalBuilder);
89 arg_types [2] = typeof (FieldAttributes);
90 arg_types [3] = typeof (int);
91 arg_types [4] = typeof (int);
92 arg_types [5] = typeof (int);
94 symwriter_define_local = type.GetMethod ("DefineLocalVariable", arg_types);
96 if (symwriter_define_local == null)
97 throw new NotSupportedException ();
101 internal void SymWriter_DefineLocalVariable (string name, LocalBuilder local,
102 FieldAttributes attributes,
103 int position, int startOffset, int endOffset)
105 if ((symbol_writer == null) || (symwriter_define_local == null))
108 object[] args = new object [6];
111 args [2] = attributes;
113 args [4] = startOffset;
114 args [5] = endOffset;
116 symwriter_define_local.Invoke (symbol_writer, args);
119 public override string FullyQualifiedName {get { return fqname;}}
122 public TypeBuilder DefineType (string name) {
123 // FIXME: LAMESPEC: what other attributes should we use here as default?
124 return DefineType (name, TypeAttributes.Public, typeof(object), null);
127 public TypeBuilder DefineType (string name, TypeAttributes attr) {
128 return DefineType (name, attr, typeof(object), null);
131 public TypeBuilder DefineType (string name, TypeAttributes attr, Type parent) {
132 return DefineType (name, attr, parent, null);
135 private TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packsize, int typesize) {
136 TypeBuilder res = new TypeBuilder (this, name, attr, parent, interfaces, packsize, typesize);
138 TypeBuilder[] new_types = new TypeBuilder [types.Length + 1];
139 System.Array.Copy (types, new_types, types.Length);
140 new_types [types.Length] = res;
143 types = new TypeBuilder [1];
146 name_cache.Add (name, res);
150 public TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, Type[] interfaces) {
151 return DefineType (name, attr, parent, interfaces, PackingSize.Unspecified, TypeBuilder.UnspecifiedTypeSize);
154 public TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, int typesize) {
155 return DefineType (name, attr, parent, null, PackingSize.Unspecified, TypeBuilder.UnspecifiedTypeSize);
158 public TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, PackingSize packsize) {
159 return DefineType (name, attr, parent, null, packsize, TypeBuilder.UnspecifiedTypeSize);
162 public TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, PackingSize packsize, int typesize) {
163 return DefineType (name, attr, parent, null, packsize, typesize);
166 public MethodInfo GetArrayMethod( Type arrayClass, string methodName, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) {
167 return new MonoArrayMethod (arrayClass, methodName, callingConvention, returnType, parameterTypes);
170 public EnumBuilder DefineEnum( string name, TypeAttributes visibility, Type underlyingType) {
171 EnumBuilder eb = new EnumBuilder (this, name, visibility, underlyingType);
175 public override Type GetType( string className) {
176 return GetType (className, false, false);
179 public override Type GetType( string className, bool ignoreCase) {
180 return GetType (className, false, ignoreCase);
183 private TypeBuilder search_in_array (TypeBuilder[] arr, string className, bool ignoreCase) {
185 if (arr == types && !ignoreCase)
186 return (TypeBuilder)name_cache [className];
187 for (i = 0; i < arr.Length; ++i) {
188 if (String.Compare (className, arr [i].FullName, ignoreCase) == 0) {
195 private TypeBuilder search_nested_in_array (TypeBuilder[] arr, string className, bool ignoreCase) {
197 for (i = 0; i < arr.Length; ++i) {
198 if (String.Compare (className, arr [i].Name, ignoreCase) == 0)
204 [MethodImplAttribute(MethodImplOptions.InternalCall)]
205 private static extern Type create_modified_type (TypeBuilder tb, string modifiers);
207 static char[] type_modifiers = {'&', '[', '*'};
209 private TypeBuilder GetMaybeNested (TypeBuilder t, string className, bool ignoreCase) {
213 subt = className.IndexOf ('+');
215 if (t.subtypes != null)
216 return search_nested_in_array (t.subtypes, className, ignoreCase);
219 if (t.subtypes != null) {
220 pname = className.Substring (0, subt);
221 rname = className.Substring (subt + 1);
222 TypeBuilder result = search_nested_in_array (t.subtypes, pname, ignoreCase);
224 return GetMaybeNested (result, rname, ignoreCase);
229 public override Type GetType( string className, bool throwOnError, bool ignoreCase) {
231 string orig = className;
233 TypeBuilder result = null;
235 if (types == null && throwOnError)
236 throw new TypeLoadException (className);
238 subt = className.IndexOfAny (type_modifiers);
240 modifiers = className.Substring (subt);
241 className = className.Substring (0, subt);
245 subt = className.IndexOf ('+');
248 result = search_in_array (types, className, ignoreCase);
251 pname = className.Substring (0, subt);
252 rname = className.Substring (subt + 1);
253 result = search_in_array (types, pname, ignoreCase);
255 result = GetMaybeNested (result, rname, ignoreCase);
257 if ((result == null) && throwOnError)
258 throw new TypeLoadException (orig);
259 if (result != null && (modifiers != null))
260 return create_modified_type (result, modifiers);
264 internal int get_next_table_index (object obj, int table, bool inc) {
265 return assemblyb.get_next_table_index (obj, table, inc);
268 public void SetCustomAttribute( CustomAttributeBuilder customBuilder) {
269 if (cattrs != null) {
270 CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1];
271 cattrs.CopyTo (new_array, 0);
272 new_array [cattrs.Length] = customBuilder;
275 cattrs = new CustomAttributeBuilder [1];
276 cattrs [0] = customBuilder;
279 public void SetCustomAttribute( ConstructorInfo con, byte[] binaryAttribute) {
280 SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
283 public ISymbolWriter GetSymWriter () {
284 return symbol_writer;
287 public ISymbolDocumentWriter DefineDocument (string url, Guid language, Guid languageVendor, Guid documentType) {
288 if (symbol_writer == null)
289 throw new InvalidOperationException ();
291 return symbol_writer.DefineDocument (url, language, languageVendor, documentType);