diff --git a/reflect/Emit/AssemblyBuilder.cs b/reflect/Emit/AssemblyBuilder.cs index 0a26aa11..12613e83 100644 --- a/reflect/Emit/AssemblyBuilder.cs +++ b/reflect/Emit/AssemblyBuilder.cs @@ -264,10 +264,12 @@ namespace IKVM.Reflection.Emit foreach (ModuleBuilder moduleBuilder in modules) { - if (string.Compare(moduleBuilder.fileName, assemblyFileName, StringComparison.OrdinalIgnoreCase) == 0) + moduleBuilder.PopulatePropertyAndEventTables(); + + if (manifestModule == null + && string.Compare(moduleBuilder.fileName, assemblyFileName, StringComparison.OrdinalIgnoreCase) == 0) { manifestModule = moduleBuilder; - break; } } diff --git a/reflect/Emit/ModuleBuilder.cs b/reflect/Emit/ModuleBuilder.cs index 177f630e..07dc278c 100644 --- a/reflect/Emit/ModuleBuilder.cs +++ b/reflect/Emit/ModuleBuilder.cs @@ -113,6 +113,17 @@ namespace IKVM.Reflection.Emit types.Add(moduleType); } + internal void PopulatePropertyAndEventTables() + { + // LAMESPEC the PropertyMap and EventMap tables are not required to be sorted by the CLI spec, + // but .NET sorts them and Mono requires them to be sorted, so we have to populate the + // tables in the right order + foreach (TypeBuilder type in types) + { + type.PopulatePropertyAndEventTables(); + } + } + internal void WriteTypeDefTable(MetadataWriter mw) { int fieldList = 1; @@ -1176,6 +1187,7 @@ namespace IKVM.Reflection.Emit public void __Save(PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine) { + PopulatePropertyAndEventTables(); IList attributes = asm.GetCustomAttributesData(null); if (attributes.Count > 0) { diff --git a/reflect/Emit/TypeBuilder.cs b/reflect/Emit/TypeBuilder.cs index 4a69aed5..8b2e0ebd 100644 --- a/reflect/Emit/TypeBuilder.cs +++ b/reflect/Emit/TypeBuilder.cs @@ -658,6 +658,29 @@ namespace IKVM.Reflection.Emit { mb.Bake(); } + if (declarativeSecurity != null) + { + this.ModuleBuilder.AddDeclarativeSecurity(token, declarativeSecurity); + } + if (baseType != null) + { + extends = this.ModuleBuilder.GetTypeToken(baseType).Token; + } + if (interfaces != null) + { + foreach (Type interfaceType in interfaces) + { + InterfaceImplTable.Record rec = new InterfaceImplTable.Record(); + rec.Class = token; + rec.Interface = this.ModuleBuilder.GetTypeToken(interfaceType).Token; + this.ModuleBuilder.InterfaceImpl.AddRecord(rec); + } + } + return new BakedType(this); + } + + internal void PopulatePropertyAndEventTables() + { if (properties != null) { PropertyMapTable.Record rec = new PropertyMapTable.Record(); @@ -680,25 +703,6 @@ namespace IKVM.Reflection.Emit eb.Bake(); } } - if (declarativeSecurity != null) - { - this.ModuleBuilder.AddDeclarativeSecurity(token, declarativeSecurity); - } - if (baseType != null) - { - extends = this.ModuleBuilder.GetTypeToken(baseType).Token; - } - if (interfaces != null) - { - foreach (Type interfaceType in interfaces) - { - InterfaceImplTable.Record rec = new InterfaceImplTable.Record(); - rec.Class = token; - rec.Interface = this.ModuleBuilder.GetTypeToken(interfaceType).Token; - this.ModuleBuilder.InterfaceImpl.AddRecord(rec); - } - } - return new BakedType(this); } public override Type BaseType