using System.Globalization;
namespace System.Reflection.Emit {
-#if NET_2_0
[ComVisible (true)]
[ComDefaultInterface (typeof (_ModuleBuilder))]
-#endif
[ClassInterface (ClassInterfaceType.None)]
public class ModuleBuilder : Module, _ModuleBuilder {
- #region Sync with reflection.h
- private IntPtr dynamic_image;
+
+#pragma warning disable 169, 414
+ #region Sync with object-internals.h
+ private UIntPtr dynamic_image; /* GC-tracked */
private int num_types;
private TypeBuilder[] types;
private CustomAttributeBuilder[] cattrs;
bool is_main;
private MonoResource[] resources;
#endregion
+#pragma warning restore 169, 414
+
private TypeBuilder global_type;
private Type global_type_created;
Hashtable name_cache;
private int[] table_indexes;
bool transient;
ModuleBuilderTokenGenerator token_gen;
- ArrayList resource_writers = null;
+ Hashtable resource_writers;
ISymbolWriter symbolWriter;
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void basic_init (ModuleBuilder ab);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void set_wrappers_type (ModuleBuilder mb, Type ab);
+
internal ModuleBuilder (AssemblyBuilder assb, string name, string fullyqname, bool emitSymbolInfo, bool transient) {
this.name = this.scopename = name;
this.fqname = fullyqname;
basic_init (this);
CreateGlobalType ();
-
+
+ if (assb.IsRun) {
+ TypeBuilder tb = new TypeBuilder (this, TypeAttributes.Abstract, 0xFFFFFF); /*last valid token*/
+ Type type = tb.CreateType ();
+ set_wrappers_type (this, type);
+ }
+
if (emitSymbolInfo) {
+#if NET_2_1 && !MONOTOUCH
+ symbolWriter = new Mono.CompilerServices.SymbolWriter.SymbolWriterImpl (this);
+#else
Assembly asm = Assembly.LoadWithPartialName ("Mono.CompilerServices.SymbolWriter");
+ if (asm == null)
+ throw new ExecutionEngineException ("The assembly for default symbol writer cannot be loaded");
+
Type t = asm.GetType ("Mono.CompilerServices.SymbolWriter.SymbolWriterImpl");
- if (t != null) {
- symbolWriter = (ISymbolWriter) Activator.CreateInstance (t, new object[] { this });
- string fileName = fqname;
- if (assemblyb.AssemblyDir != null)
- fileName = Path.Combine (assemblyb.AssemblyDir, fileName);
- symbolWriter.Initialize (IntPtr.Zero, fileName, true);
- }
+ if (t == null)
+ throw new ExecutionEngineException ("The type that implements the default symbol writer interface cannot be found");
+
+ symbolWriter = (ISymbolWriter) Activator.CreateInstance (t, new object[] { this });
+#endif
+ string fileName = fqname;
+ if (assemblyb.AssemblyDir != null)
+ fileName = Path.Combine (assemblyb.AssemblyDir, fileName);
+ symbolWriter.Initialize (IntPtr.Zero, fileName, true);
}
}
return fb;
}
- public FieldBuilder DefineUninitializedData( string name, int size, FieldAttributes attributes) {
+ public FieldBuilder DefineUninitializedData (string name, int size, FieldAttributes attributes)
+ {
if (name == null)
throw new ArgumentNullException ("name");
if (global_type_created != null)
throw new InvalidOperationException ("global fields already created");
- if (global_type == null)
- global_type = new TypeBuilder (this, 0);
+ if ((size <= 0) || (size > 0x3f0000))
+ throw new ArgumentException ("size", "Data size must be > 0 and < 0x3f0000");
+
+ CreateGlobalType ();
string typeName = "$ArrayType$" + size;
Type datablobtype = GetType (typeName, false, false);
return DefineGlobalMethod (name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null);
}
-#if NET_2_0 || BOOTSTRAP_NET_2_0
- public
-#else
- internal
-#endif
- MethodBuilder DefineGlobalMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
+ public MethodBuilder DefineGlobalMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
{
if (name == null)
throw new ArgumentNullException ("name");
throw new ArgumentException ("global methods must be static");
if (global_type_created != null)
throw new InvalidOperationException ("global methods already created");
- if (global_type == null)
- global_type = new TypeBuilder (this, 0);
+ CreateGlobalType ();
MethodBuilder mb = global_type.DefineMethod (name, attributes, callingConvention, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
addGlobalMethod (mb);
throw new ArgumentException ("global methods must be static");
if (global_type_created != null)
throw new InvalidOperationException ("global methods already created");
- if (global_type == null)
- global_type = new TypeBuilder (this, 0);
+ CreateGlobalType ();
MethodBuilder mb = global_type.DefinePInvokeMethod (name, dllName, entryName, attributes, callingConvention, returnType, parameterTypes, nativeCallConv, nativeCharSet);
addGlobalMethod (mb);
num_types ++;
}
- private TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packsize, int typesize) {
- if (name_cache.Contains (name))
- throw new ArgumentException ("Duplicate type name within an assembly.");
-
- TypeBuilder res = new TypeBuilder (this, name, attr, parent, interfaces, packsize, typesize, null);
+ private TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packingSize, int typesize) {
+ TypeBuilder res = new TypeBuilder (this, name, attr, parent, interfaces, packingSize, typesize, null);
AddType (res);
- name_cache.Add (name, res);
+
+ try {
+ name_cache.Add (name, res);
+ } catch {
+ throw new ArgumentException ("Duplicate type name within an assembly.");
+ }
+
return res;
}
- internal void RegisterTypeName (TypeBuilder tb, string name) {
+ internal void RegisterTypeName (TypeBuilder tb, string name)
+ {
name_cache.Add (name, tb);
}
+
+ internal TypeBuilder GetRegisteredType (string name)
+ {
+ return (TypeBuilder) name_cache [name];
+ }
-#if NET_2_0
[ComVisible (true)]
-#endif
public TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, Type[] interfaces) {
return DefineType (name, attr, parent, interfaces, PackingSize.Unspecified, TypeBuilder.UnspecifiedTypeSize);
}
return DefineType (name, attr, parent, null, packsize, TypeBuilder.UnspecifiedTypeSize);
}
- public TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, PackingSize packsize, int typesize) {
- return DefineType (name, attr, parent, null, packsize, typesize);
+ public TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, PackingSize packingSize, int typesize) {
+ return DefineType (name, attr, parent, null, packingSize, typesize);
}
public MethodInfo GetArrayMethod( Type arrayClass, string methodName, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) {
return eb;
}
-#if NET_2_0
[ComVisible (true)]
-#endif
public override Type GetType( string className) {
return GetType (className, false, false);
}
-#if NET_2_0
[ComVisible (true)]
-#endif
public override Type GetType( string className, bool ignoreCase) {
return GetType (className, false, ignoreCase);
}
return null;
}
-#if NET_2_0
[ComVisible (true)]
-#endif
- public override Type GetType (string className, bool throwOnError, bool ignoreCase) {
+ public override Type GetType (string className, bool throwOnError, bool ignoreCase)
+ {
+ if (className == null)
+ throw new ArgumentNullException ("className");
+ if (className.Length == 0)
+ throw new ArgumentException ("className");
+
int subt;
string orig = className;
string modifiers;
}
if ((result == null) && throwOnError)
throw new TypeLoadException (orig);
- if (result != null && (modifiers != null))
- return create_modified_type (result, modifiers);
- return result;
+ if (result != null && (modifiers != null)) {
+ Type mt = create_modified_type (result, modifiers);
+ result = mt as TypeBuilder;
+ if (result == null)
+ return mt;
+ }
+ if (result != null && result.is_created)
+ return result.CreateType ();
+ else
+ return result;
}
internal int get_next_table_index (object obj, int table, bool inc) {
}
}
-#if NET_2_0
[ComVisible (true)]
-#endif
public void SetCustomAttribute( ConstructorInfo con, byte[] binaryAttribute) {
SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
}
public override Type [] GetTypes ()
{
if (types == null)
- return new TypeBuilder [0];
+ return Type.EmptyTypes;
int n = num_types;
- TypeBuilder [] copy = new TypeBuilder [n];
+ Type [] copy = new Type [n];
Array.Copy (types, copy, n);
+ // MS replaces the typebuilders with their created types
+ for (int i = 0; i < copy.Length; ++i)
+ if (types [i].is_created)
+ copy [i] = types [i].CreateType ();
+
return copy;
}
throw new InvalidOperationException ("The assembly is transient");
ResourceWriter writer = new ResourceWriter (new MemoryStream ());
if (resource_writers == null)
- resource_writers = new ArrayList ();
- resource_writers.Add (writer);
+ resource_writers = new Hashtable ();
+ resource_writers [name] = writer;
// The data is filled out later
if (resources != null) {
throw new NotImplementedException ();
}
-#if NET_2_0
public void DefineManifestResource (string name, Stream stream, ResourceAttributes attribute) {
if (name == null)
throw new ArgumentNullException ("name");
resources [p].attrs = attribute;
resources [p].stream = stream;
}
-#endif
[MonoTODO]
public void SetSymCustomAttribute (string name, byte[] data)
return GetMethodToken (GetArrayMethod (arrayClass, methodName, callingConvention, returnType, parameterTypes));
}
-#if NET_2_0
[ComVisible (true)]
-#endif
public MethodToken GetConstructorToken (ConstructorInfo con)
{
if (con == null)
return new TypeToken (GetToken (type));
}
- public TypeToken GetTypeToken (string type)
+ public TypeToken GetTypeToken (string name)
{
return GetTypeToken (GetType (name));
}
return getToken (this, helper);
}
+ /*
+ * Register the token->obj mapping with the runtime so the Module.Resolve...
+ * methods will work for obj.
+ */
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal extern void RegisterToken (object obj, int token);
+
internal TokenGenerator GetTokenGenerator () {
if (token_gen == null)
token_gen = new ModuleBuilderTokenGenerator (this);
if ((global_type != null) && (global_type_created == null))
global_type_created = global_type.CreateType ();
- if (resource_writers != null) {
- for (int i = 0; i < resource_writers.Count; ++i) {
- ResourceWriter writer = (ResourceWriter)resource_writers [i];
- writer.Generate ();
- MemoryStream stream = (MemoryStream)writer.Stream;
- resources [i].data = new byte [stream.Length];
- stream.Seek (0, SeekOrigin.Begin);
- stream.Read (resources [i].data, 0, (int)stream.Length);
- }
- }
-
if (resources != null) {
for (int i = 0; i < resources.Length; ++i) {
+ IResourceWriter rwriter;
+ if (resource_writers != null && (rwriter = resource_writers [resources [i].name] as IResourceWriter) != null) {
+ ResourceWriter writer = (ResourceWriter)rwriter;
+ writer.Generate ();
+ MemoryStream mstream = (MemoryStream)writer.Stream;
+ resources [i].data = new byte [mstream.Length];
+ mstream.Seek (0, SeekOrigin.Begin);
+ mstream.Read (resources [i].data, 0, (int)mstream.Length);
+ continue;
+ }
Stream stream = resources [i].stream;
// According to MSDN docs, the stream is read during assembly save, not earlier
internal void CreateGlobalType () {
if (global_type == null)
- global_type = new TypeBuilder (this, 0);
+ global_type = new TypeBuilder (this, 0, 1);
+ }
+
+ internal override Guid GetModuleVersionId ()
+ {
+ return new Guid (guid);
}
+ // Used by mcs, the symbol writer, and mdb through reflection
internal static Guid Mono_GetGuid (ModuleBuilder mb)
{
- return new Guid (mb.guid);
+ return mb.GetModuleVersionId ();
}
void _ModuleBuilder.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)