From 29f274c5d1acec1130683cbdd77daf309a21f909 Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Tue, 20 Nov 2012 17:48:01 +0100 Subject: [PATCH] Update to the latest IKVM.Reflection --- mcs/class/IKVM.Reflection/Assembly.cs | 67 +++- mcs/class/IKVM.Reflection/AssemblyName.cs | 75 +++- .../IKVM.Reflection/CustomAttributeData.cs | 8 +- .../CustomAttributeNamedArgument.cs | 10 + mcs/class/IKVM.Reflection/CustomModifiers.cs | 2 +- .../IKVM.Reflection/Emit/AssemblyBuilder.cs | 23 +- .../Emit/ConstructorBuilder.cs | 6 + .../Emit/CustomAttributeBuilder.cs | 2 +- mcs/class/IKVM.Reflection/Emit/EnumBuilder.cs | 5 + .../IKVM.Reflection/Emit/EventBuilder.cs | 2 +- .../IKVM.Reflection/Emit/ExceptionHandler.cs | 121 +++++++ mcs/class/IKVM.Reflection/Emit/ILGenerator.cs | 341 ++++++++---------- .../IKVM.Reflection/Emit/MethodBuilder.cs | 52 +++ .../IKVM.Reflection/Emit/ModuleBuilder.cs | 7 +- .../IKVM.Reflection/Emit/PropertyBuilder.cs | 2 +- .../IKVM.Reflection/Emit/SignatureHelper.cs | 4 +- mcs/class/IKVM.Reflection/Emit/Tokens.cs | 10 - mcs/class/IKVM.Reflection/Emit/TypeBuilder.cs | 16 +- mcs/class/IKVM.Reflection/Enums.cs | 3 +- mcs/class/IKVM.Reflection/EventInfo.cs | 15 + mcs/class/IKVM.Reflection/Fusion.cs | 9 +- .../IKVM.Reflection/IKVM.Reflection.csproj | 4 + .../IKVM.Reflection/LocalVariableInfo.cs | 14 +- mcs/class/IKVM.Reflection/MarshalSpec.cs | 58 +-- mcs/class/IKVM.Reflection/MemberInfo.cs | 10 + .../IKVM.Reflection/Metadata/CliHeader.cs | 33 +- mcs/class/IKVM.Reflection/Metadata/Tables.cs | 6 +- mcs/class/IKVM.Reflection/MethodBase.cs | 5 + mcs/class/IKVM.Reflection/MethodSignature.cs | 10 +- mcs/class/IKVM.Reflection/Missing.cs | 14 +- mcs/class/IKVM.Reflection/Module.cs | 15 + mcs/class/IKVM.Reflection/ParameterInfo.cs | 15 + mcs/class/IKVM.Reflection/PropertyInfo.cs | 10 + .../IKVM.Reflection/PropertySignature.cs | 4 +- .../IKVM.Reflection/Reader/AssemblyReader.cs | 67 +++- .../IKVM.Reflection/Reader/Authenticode.cs | 15 + .../IKVM.Reflection/Reader/ByteReader.cs | 29 +- .../IKVM.Reflection/Reader/ModuleReader.cs | 54 +-- mcs/class/IKVM.Reflection/Reader/PEReader.cs | 6 - mcs/class/IKVM.Reflection/Signature.cs | 51 ++- mcs/class/IKVM.Reflection/Type.cs | 97 ++++- mcs/class/IKVM.Reflection/Universe.cs | 18 + .../IKVM.Reflection/Writer/ByteBuffer.cs | 39 +- mcs/class/IKVM.Reflection/Writer/Heaps.cs | 8 +- .../IKVM.Reflection/Writer/MetadataWriter.cs | 4 +- .../IKVM.Reflection/Writer/ModuleWriter.cs | 2 +- mcs/class/IKVM.Reflection/reflect.build | 3 + mcs/mcs/method.cs | 4 +- 48 files changed, 989 insertions(+), 386 deletions(-) create mode 100644 mcs/class/IKVM.Reflection/Emit/ExceptionHandler.cs create mode 100644 mcs/class/IKVM.Reflection/Reader/Authenticode.cs diff --git a/mcs/class/IKVM.Reflection/Assembly.cs b/mcs/class/IKVM.Reflection/Assembly.cs index 715e774bdeb..5f3a5fa8674 100644 --- a/mcs/class/IKVM.Reflection/Assembly.cs +++ b/mcs/class/IKVM.Reflection/Assembly.cs @@ -26,10 +26,13 @@ using System.Collections.Generic; namespace IKVM.Reflection { + public delegate Module ModuleResolveEventHandler(object sender, ResolveEventArgs e); + public abstract class Assembly : ICustomAttributeProvider { internal readonly Universe universe; protected string fullName; // AssemblyBuilder needs access to this field to clear it when the name changes + protected List resolvers; internal Assembly(Universe universe) { @@ -41,6 +44,22 @@ namespace IKVM.Reflection return FullName; } + public event ModuleResolveEventHandler ModuleResolve + { + add + { + if (resolvers == null) + { + resolvers = new List(); + } + resolvers.Add(value); + } + remove + { + resolvers.Remove(value); + } + } + public abstract Type[] GetTypes(); public abstract AssemblyName GetName(); public abstract string ImageRuntimeVersion { get; } @@ -76,6 +95,11 @@ namespace IKVM.Reflection return GetModules(true); } + public IEnumerable Modules + { + get { return GetLoadedModules(); } + } + public Module[] GetLoadedModules() { return GetLoadedModules(true); @@ -104,6 +128,25 @@ namespace IKVM.Reflection return list.ToArray(); } + public IEnumerable ExportedTypes + { + get { return GetExportedTypes(); } + } + + public IEnumerable DefinedTypes + { + get + { + Type[] types = GetTypes(); + TypeInfo[] typeInfos = new TypeInfo[types.Length]; + for (int i = 0; i < types.Length; i++) + { + typeInfos[i] = types[i].GetTypeInfo(); + } + return typeInfos; + } + } + public Type GetType(string name) { return GetType(name, false); @@ -163,6 +206,16 @@ namespace IKVM.Reflection return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit); } + public IList GetCustomAttributesData() + { + return CustomAttributeData.GetCustomAttributes(this); + } + + public IEnumerable CustomAttributes + { + get { return GetCustomAttributesData(); } + } + public static string CreateQualifiedName(string assemblyName, string typeName) { return typeName + ", " + assemblyName; @@ -186,14 +239,24 @@ namespace IKVM.Reflection } } + public virtual bool IsDynamic + { + get { return false; } + } + public virtual bool __IsMissing { get { return false; } } - public virtual AssemblyNameFlags __AssemblyFlags + public AssemblyNameFlags __AssemblyFlags + { + get { return GetAssemblyFlags(); } + } + + protected virtual AssemblyNameFlags GetAssemblyFlags() { - get { return GetName().Flags; } + return GetName().Flags; } internal abstract IList GetCustomAttributesData(Type attributeType); diff --git a/mcs/class/IKVM.Reflection/AssemblyName.cs b/mcs/class/IKVM.Reflection/AssemblyName.cs index 0812194b844..beae6ad0cb8 100644 --- a/mcs/class/IKVM.Reflection/AssemblyName.cs +++ b/mcs/class/IKVM.Reflection/AssemblyName.cs @@ -25,6 +25,7 @@ using System; using System.Globalization; using System.Configuration.Assemblies; using System.IO; +using System.Security.Cryptography; using System.Text; using IKVM.Reflection.Reader; @@ -41,6 +42,7 @@ namespace IKVM.Reflection private AssemblyNameFlags flags; private AssemblyHashAlgorithm hashAlgorithm; private AssemblyVersionCompatibility versionCompatibility = AssemblyVersionCompatibility.SameMachine; + private ProcessorArchitecture processorArchitecture; private string codeBase; internal byte[] hash; @@ -62,9 +64,8 @@ namespace IKVM.Reflection switch (Fusion.ParseAssemblyName(assemblyName, out parsed)) { case ParseAssemblyResult.GenericError: - throw new FileLoadException(); case ParseAssemblyResult.DuplicateKey: - throw new System.Runtime.InteropServices.COMException(); + throw new FileLoadException(); } name = parsed.Name; if (parsed.Culture != null) @@ -99,12 +100,7 @@ namespace IKVM.Reflection } else { - publicKeyToken = new byte[8]; - for (int i = 0, pos = 0; i < publicKeyToken.Length; i++, pos += 2) - { - publicKeyToken[i] = (byte)("0123456789abcdef".IndexOf(char.ToLowerInvariant(parsed.PublicKeyToken[pos])) * 16 - + "0123456789abcdef".IndexOf(char.ToLowerInvariant(parsed.PublicKeyToken[pos + 1]))); - } + publicKeyToken = ParseKey(parsed.PublicKeyToken); } } if (parsed.Retargetable.HasValue) @@ -125,6 +121,40 @@ namespace IKVM.Reflection } } + private static byte[] ParseKey(string key) + { + if ((key.Length & 1) != 0) + { + throw new FileLoadException(); + } + byte[] buf = new byte[key.Length / 2]; + for (int i = 0; i < buf.Length; i++) + { + buf[i] = (byte)(ParseHexDigit(key[i * 2]) * 16 + ParseHexDigit(key[i * 2 + 1])); + } + return buf; + } + + private static int ParseHexDigit(char digit) + { + if (digit >= '0' && digit <= '9') + { + return digit - '0'; + } + else + { + digit |= (char)0x20; + if (digit >= 'a' && digit <= 'f') + { + return 10 + digit - 'a'; + } + else + { + throw new FileLoadException(); + } + } + } + public override string ToString() { return FullName; @@ -142,6 +172,11 @@ namespace IKVM.Reflection set { culture = value == null ? null : value.Name; } } + public string CultureName + { + get { return culture; } + } + internal string Culture { get { return culture; } @@ -179,11 +214,12 @@ namespace IKVM.Reflection public ProcessorArchitecture ProcessorArchitecture { - get { return (ProcessorArchitecture)(((int)flags & 0x70) >> 4); } + get { return processorArchitecture; } set { if (value >= ProcessorArchitecture.None && value <= ProcessorArchitecture.Arm) { + processorArchitecture = value; flags = (flags & ~(AssemblyNameFlags)0x70) | (AssemblyNameFlags)((int)value << 4); } } @@ -351,17 +387,20 @@ namespace IKVM.Reflection { return publicKey; } - // HACK use the real AssemblyName to convert PublicKey to PublicKeyToken - StringBuilder sb = new StringBuilder("Foo, PublicKey=", 20 + publicKey.Length * 2); - AppendPublicKey(sb, publicKey); - string str = sb.ToString(); - if (str == "Foo, PublicKey=00000000000000000400000000000000") + byte[] hash = new SHA1Managed().ComputeHash(publicKey); + byte[] token = new byte[8]; + for (int i = 0; i < token.Length; i++) { - // MONOBUG workaround Mono 2.10 bug (fixed in 2.11) - // it does not return the correct public key token for the ECMA key - return new byte[] { 0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89 }; + token[i] = hash[hash.Length - 1 - i]; } - return new System.Reflection.AssemblyName(str).GetPublicKeyToken(); + return token; + } + + internal static string ComputePublicKeyToken(string publicKey) + { + StringBuilder sb = new StringBuilder(16); + AppendPublicKey(sb, ComputePublicKeyToken(ParseKey(publicKey))); + return sb.ToString(); } private static void AppendPublicKey(StringBuilder sb, byte[] publicKey) diff --git a/mcs/class/IKVM.Reflection/CustomAttributeData.cs b/mcs/class/IKVM.Reflection/CustomAttributeData.cs index 72026fb9b4d..6c4c2a7b641 100644 --- a/mcs/class/IKVM.Reflection/CustomAttributeData.cs +++ b/mcs/class/IKVM.Reflection/CustomAttributeData.cs @@ -243,13 +243,13 @@ namespace IKVM.Reflection if (br.PeekByte() == '.') { br.ReadByte(); - int count = br.ReadCompressedInt(); + int count = br.ReadCompressedUInt(); for (int j = 0; j < count; j++) { Type type = ReadType(asm, br); ConstructorInfo constructor = type.GetPseudoCustomAttributeConstructor(u.System_Security_Permissions_SecurityAction); // LAMESPEC there is an additional length here (probably of the named argument list) - byte[] blob = br.ReadBytes(br.ReadCompressedInt()); + byte[] blob = br.ReadBytes(br.ReadCompressedUInt()); list.Add(new CustomAttributeData(asm, constructor, action, blob, index)); } } @@ -601,7 +601,7 @@ namespace IKVM.Reflection // 5) Unresolved declarative security ByteReader br = new ByteReader(declSecurityBlob, 0, declSecurityBlob.Length); // LAMESPEC the count of named arguments is a compressed integer (instead of UInt16 as NumNamed in custom attributes) - lazyNamedArguments = ReadNamedArguments(module.Assembly, br, br.ReadCompressedInt(), Constructor.DeclaringType); + lazyNamedArguments = ReadNamedArguments(module.Assembly, br, br.ReadCompressedUInt(), Constructor.DeclaringType); } } return lazyNamedArguments; @@ -736,7 +736,7 @@ namespace IKVM.Reflection } ModuleBuilder mb = module as ModuleBuilder; int token = parameter.MetadataToken; - if (mb != null && mb.IsSaved && mb.IsPseudoToken(token)) + if (mb != null && mb.IsSaved && ModuleBuilder.IsPseudoToken(token)) { token = mb.ResolvePseudoToken(token); } diff --git a/mcs/class/IKVM.Reflection/CustomAttributeNamedArgument.cs b/mcs/class/IKVM.Reflection/CustomAttributeNamedArgument.cs index d9a84b7a74a..4b4a8ea8c80 100644 --- a/mcs/class/IKVM.Reflection/CustomAttributeNamedArgument.cs +++ b/mcs/class/IKVM.Reflection/CustomAttributeNamedArgument.cs @@ -58,6 +58,16 @@ namespace IKVM.Reflection get { return value; } } + public bool IsField + { + get { return member.MemberType == MemberTypes.Field; } + } + + public string MemberName + { + get { return member.Name; } + } + public static bool operator ==(CustomAttributeNamedArgument arg1, CustomAttributeNamedArgument arg2) { return arg1.member.Equals(arg2.member) && arg1.value == arg2.value; diff --git a/mcs/class/IKVM.Reflection/CustomModifiers.cs b/mcs/class/IKVM.Reflection/CustomModifiers.cs index e8670614e96..dade700ac14 100644 --- a/mcs/class/IKVM.Reflection/CustomModifiers.cs +++ b/mcs/class/IKVM.Reflection/CustomModifiers.cs @@ -293,7 +293,7 @@ namespace IKVM.Reflection while (IsCustomModifier(b)) { br.ReadByte(); - br.ReadCompressedInt(); + br.ReadCompressedUInt(); b = br.PeekByte(); } } diff --git a/mcs/class/IKVM.Reflection/Emit/AssemblyBuilder.cs b/mcs/class/IKVM.Reflection/Emit/AssemblyBuilder.cs index ceabeac73af..910a6db8a7c 100644 --- a/mcs/class/IKVM.Reflection/Emit/AssemblyBuilder.cs +++ b/mcs/class/IKVM.Reflection/Emit/AssemblyBuilder.cs @@ -180,16 +180,26 @@ namespace IKVM.Reflection.Emit this.hashAlgorithm = hashAlgorithm; } + [Obsolete("Use __AssemblyFlags property instead.")] public void __SetAssemblyFlags(AssemblyNameFlags flags) { - AssemblyName oldName = GetName(); - this.flags = flags; - Rename(oldName); + this.__AssemblyFlags = flags; + } + + protected override AssemblyNameFlags GetAssemblyFlags() + { + return flags; } - public override AssemblyNameFlags __AssemblyFlags + public new AssemblyNameFlags __AssemblyFlags { get { return flags; } + set + { + AssemblyName oldName = GetName(); + this.flags = value; + Rename(oldName); + } } internal string Name @@ -730,6 +740,11 @@ namespace IKVM.Reflection.Emit throw new NotSupportedException(); } + public override bool IsDynamic + { + get { return true; } + } + internal override IList GetCustomAttributesData(Type attributeType) { List list = new List(); diff --git a/mcs/class/IKVM.Reflection/Emit/ConstructorBuilder.cs b/mcs/class/IKVM.Reflection/Emit/ConstructorBuilder.cs index 308679dbb85..02ccca1fe4f 100644 --- a/mcs/class/IKVM.Reflection/Emit/ConstructorBuilder.cs +++ b/mcs/class/IKVM.Reflection/Emit/ConstructorBuilder.cs @@ -22,6 +22,7 @@ */ using System; +using System.Collections.Generic; namespace IKVM.Reflection.Emit { @@ -122,6 +123,11 @@ namespace IKVM.Reflection.Emit set { methodBuilder.InitLocals = value; } } + public void SetMethodBody(byte[] il, int maxStack, byte[] localSignature, IEnumerable exceptionHandlers, IEnumerable tokenFixups) + { + methodBuilder.SetMethodBody(il, maxStack, localSignature, exceptionHandlers, tokenFixups); + } + internal override MethodInfo GetMethodInfo() { return methodBuilder; diff --git a/mcs/class/IKVM.Reflection/Emit/CustomAttributeBuilder.cs b/mcs/class/IKVM.Reflection/Emit/CustomAttributeBuilder.cs index 12be4a466d4..2b9708b5c12 100644 --- a/mcs/class/IKVM.Reflection/Emit/CustomAttributeBuilder.cs +++ b/mcs/class/IKVM.Reflection/Emit/CustomAttributeBuilder.cs @@ -377,7 +377,7 @@ namespace IKVM.Reflection.Emit private void WritePackedLen(int len) { - bb.WriteCompressedInt(len); + bb.WriteCompressedUInt(len); } private void WriteFieldOrPropType(Type type) diff --git a/mcs/class/IKVM.Reflection/Emit/EnumBuilder.cs b/mcs/class/IKVM.Reflection/Emit/EnumBuilder.cs index e93e7e736dd..eacacb01f5b 100644 --- a/mcs/class/IKVM.Reflection/Emit/EnumBuilder.cs +++ b/mcs/class/IKVM.Reflection/Emit/EnumBuilder.cs @@ -86,6 +86,11 @@ namespace IKVM.Reflection.Emit return typeBuilder.CreateType(); } + public TypeInfo CreateTypeInfo() + { + return typeBuilder.CreateTypeInfo(); + } + public TypeToken TypeToken { get { return typeBuilder.TypeToken; } diff --git a/mcs/class/IKVM.Reflection/Emit/EventBuilder.cs b/mcs/class/IKVM.Reflection/Emit/EventBuilder.cs index 6e98d3711ea..03242720cb4 100644 --- a/mcs/class/IKVM.Reflection/Emit/EventBuilder.cs +++ b/mcs/class/IKVM.Reflection/Emit/EventBuilder.cs @@ -268,7 +268,7 @@ namespace IKVM.Reflection.Emit internal override int GetCurrentToken() { - if (typeBuilder.ModuleBuilder.IsSaved && typeBuilder.ModuleBuilder.IsPseudoToken(lazyPseudoToken)) + if (typeBuilder.ModuleBuilder.IsSaved && ModuleBuilder.IsPseudoToken(lazyPseudoToken)) { return typeBuilder.ModuleBuilder.ResolvePseudoToken(lazyPseudoToken); } diff --git a/mcs/class/IKVM.Reflection/Emit/ExceptionHandler.cs b/mcs/class/IKVM.Reflection/Emit/ExceptionHandler.cs new file mode 100644 index 00000000000..40837a97a4a --- /dev/null +++ b/mcs/class/IKVM.Reflection/Emit/ExceptionHandler.cs @@ -0,0 +1,121 @@ +/* + Copyright (C) 2012 Jeroen Frijters + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jeroen Frijters + jeroen@frijters.net + +*/ +using System; +using System.Collections.Generic; + +namespace IKVM.Reflection.Emit +{ + public struct ExceptionHandler : IEquatable + { + private readonly int tryOffset; + private readonly int tryLength; + private readonly int filterOffset; + private readonly int handlerOffset; + private readonly int handlerLength; + private readonly ExceptionHandlingClauseOptions kind; + private readonly int exceptionTypeToken; + + public ExceptionHandler(int tryOffset, int tryLength, int filterOffset, int handlerOffset, int handlerLength, ExceptionHandlingClauseOptions kind, int exceptionTypeToken) + { + if (tryOffset < 0 || tryLength < 0 || filterOffset < 0 || handlerOffset < 0 || handlerLength < 0) + { + throw new ArgumentOutOfRangeException(); + } + this.tryOffset = tryOffset; + this.tryLength = tryLength; + this.filterOffset = filterOffset; + this.handlerOffset = handlerOffset; + this.handlerLength = handlerLength; + this.kind = kind; + this.exceptionTypeToken = exceptionTypeToken; + } + + public int TryOffset + { + get { return tryOffset; } + } + + public int TryLength + { + get { return tryLength; } + } + + public int FilterOffset + { + get { return filterOffset; } + } + + public int HandlerOffset + { + get { return handlerOffset; } + } + + public int HandlerLength + { + get { return handlerLength; } + } + + public ExceptionHandlingClauseOptions Kind + { + get { return kind; } + } + + public int ExceptionTypeToken + { + get { return exceptionTypeToken; } + } + + public bool Equals(ExceptionHandler other) + { + return tryOffset == other.tryOffset + && tryLength == other.tryLength + && filterOffset == other.filterOffset + && handlerOffset == other.handlerOffset + && handlerLength == other.handlerLength + && kind == other.kind + && exceptionTypeToken == other.exceptionTypeToken; + } + + public override bool Equals(object obj) + { + ExceptionHandler? other = obj as ExceptionHandler?; + return other != null && Equals(other); + } + + public override int GetHashCode() + { + return tryOffset ^ tryLength * 33 ^ filterOffset * 333 ^ handlerOffset * 3333 ^ handlerLength * 33333; + } + + public static bool operator ==(ExceptionHandler left, ExceptionHandler right) + { + return left.Equals(right); + } + + public static bool operator !=(ExceptionHandler left, ExceptionHandler right) + { + return !left.Equals(right); + } + } +} diff --git a/mcs/class/IKVM.Reflection/Emit/ILGenerator.cs b/mcs/class/IKVM.Reflection/Emit/ILGenerator.cs index 7fddd7bcdb6..b7be3f3a981 100644 --- a/mcs/class/IKVM.Reflection/Emit/ILGenerator.cs +++ b/mcs/class/IKVM.Reflection/Emit/ILGenerator.cs @@ -71,20 +71,20 @@ namespace IKVM.Reflection.Emit } } - public sealed class LocalBuilder + public sealed class LocalBuilder : LocalVariableInfo { - private readonly Type localType; - private readonly int index; - private readonly bool pinned; internal string name; internal int startOffset; internal int endOffset; internal LocalBuilder(Type localType, int index, bool pinned) + : base(index, localType, pinned) + { + } + + internal LocalBuilder(Type localType, int index, bool pinned, CustomModifiers customModifiers) + : base(index, localType, pinned, customModifiers) { - this.localType = localType; - this.index = index; - this.pinned = pinned; } public void SetLocalSymInfo(string name) @@ -98,21 +98,6 @@ namespace IKVM.Reflection.Emit this.startOffset = startOffset; this.endOffset = endOffset; } - - public Type LocalType - { - get { return localType; } - } - - public int LocalIndex - { - get { return index; } - } - - public bool IsPinned - { - get { return pinned; } - } } public sealed class ILGenerator @@ -143,7 +128,7 @@ namespace IKVM.Reflection.Emit internal int offset; } - private sealed class ExceptionBlock : IComparer + internal sealed class ExceptionBlock : IComparer { internal readonly int ordinal; internal Label labelEnd; @@ -151,14 +136,25 @@ namespace IKVM.Reflection.Emit internal int tryLength; internal int handlerOffset; internal int handlerLength; - internal Type exceptionType; // MarkerType.Finally = finally block, MarkerType.Filter = handler with filter, MarkerType.Fault = fault block - internal int filterOffset; + internal int filterOffsetOrExceptionTypeToken; + internal ExceptionHandlingClauseOptions kind; internal ExceptionBlock(int ordinal) { this.ordinal = ordinal; } + internal ExceptionBlock(ExceptionHandler h) + { + this.ordinal = -1; + this.tryOffset = h.TryOffset; + this.tryLength = h.TryLength; + this.handlerOffset = h.HandlerOffset; + this.handlerLength = h.HandlerLength; + this.kind = h.Kind; + this.filterOffsetOrExceptionTypeToken = kind == ExceptionHandlingClauseOptions.Filter ? h.FilterOffset : h.ExceptionTypeToken; + } + int IComparer.Compare(ExceptionBlock x, ExceptionBlock y) { // Mono's sort insists on doing unnecessary comparisons @@ -258,56 +254,57 @@ namespace IKVM.Reflection.Emit public void BeginCatchBlock(Type exceptionType) { - ExceptionBlock block = exceptionStack.Peek(); - if (exceptionBlockAssistanceMode == EBAM_COMPAT || (exceptionBlockAssistanceMode == EBAM_CLEVER && stackHeight != -1)) + if (exceptionType == null) { - if (exceptionType == null) + // this must be a catch block after a filter + ExceptionBlock block = exceptionStack.Peek(); + if (block.kind != ExceptionHandlingClauseOptions.Filter || block.handlerOffset != 0) { - Emit(OpCodes.Endfilter); + throw new ArgumentNullException("exceptionType"); } - else + if (exceptionBlockAssistanceMode == EBAM_COMPAT || (exceptionBlockAssistanceMode == EBAM_CLEVER && stackHeight != -1)) { - Emit(OpCodes.Leave, block.labelEnd); + Emit(OpCodes.Endfilter); } + stackHeight = 0; + UpdateStack(1); + block.handlerOffset = code.Position; + } + else + { + ExceptionBlock block = BeginCatchOrFilterBlock(); + block.kind = ExceptionHandlingClauseOptions.Clause; + block.filterOffsetOrExceptionTypeToken = moduleBuilder.GetTypeTokenForMemberRef(exceptionType); + block.handlerOffset = code.Position; + } + } + + private ExceptionBlock BeginCatchOrFilterBlock() + { + ExceptionBlock block = exceptionStack.Peek(); + if (exceptionBlockAssistanceMode == EBAM_COMPAT || (exceptionBlockAssistanceMode == EBAM_CLEVER && stackHeight != -1)) + { + Emit(OpCodes.Leave, block.labelEnd); } stackHeight = 0; UpdateStack(1); - if (exceptionType == null) + if (block.tryLength == 0) { - if (block.exceptionType != MarkerType.Filter || block.handlerOffset != 0) - { - throw new ArgumentNullException("exceptionType"); - } - block.handlerOffset = code.Position; + block.tryLength = code.Position - block.tryOffset; } else { - if (block.tryLength == 0) - { - block.tryLength = code.Position - block.tryOffset; - } - else - { - block.handlerLength = code.Position - block.handlerOffset; - exceptionStack.Pop(); - ExceptionBlock newBlock = new ExceptionBlock(exceptions.Count); - newBlock.labelEnd = block.labelEnd; - newBlock.tryOffset = block.tryOffset; - newBlock.tryLength = block.tryLength; - block = newBlock; - exceptions.Add(block); - exceptionStack.Push(block); - } - block.exceptionType = exceptionType; - if (exceptionType == MarkerType.Filter) - { - block.filterOffset = code.Position; - } - else - { - block.handlerOffset = code.Position; - } + block.handlerLength = code.Position - block.handlerOffset; + exceptionStack.Pop(); + ExceptionBlock newBlock = new ExceptionBlock(exceptions.Count); + newBlock.labelEnd = block.labelEnd; + newBlock.tryOffset = block.tryOffset; + newBlock.tryLength = block.tryLength; + block = newBlock; + exceptions.Add(block); + exceptionStack.Push(block); } + return block; } public Label BeginExceptionBlock() @@ -323,20 +320,22 @@ namespace IKVM.Reflection.Emit public void BeginExceptFilterBlock() { - BeginCatchBlock(MarkerType.Filter); + ExceptionBlock block = BeginCatchOrFilterBlock(); + block.kind = ExceptionHandlingClauseOptions.Filter; + block.filterOffsetOrExceptionTypeToken = code.Position; } public void BeginFaultBlock() { - BeginFinallyFaultBlock(MarkerType.Fault); + BeginFinallyFaultBlock(ExceptionHandlingClauseOptions.Fault); } public void BeginFinallyBlock() { - BeginFinallyFaultBlock(MarkerType.Finally); + BeginFinallyFaultBlock(ExceptionHandlingClauseOptions.Finally); } - private void BeginFinallyFaultBlock(Type type) + private void BeginFinallyFaultBlock(ExceptionHandlingClauseOptions kind) { ExceptionBlock block = exceptionStack.Peek(); if (exceptionBlockAssistanceMode == EBAM_COMPAT || (exceptionBlockAssistanceMode == EBAM_CLEVER && stackHeight != -1)) @@ -371,7 +370,7 @@ namespace IKVM.Reflection.Emit exceptionStack.Push(block); } block.handlerOffset = code.Position; - block.exceptionType = type; + block.kind = kind; stackHeight = 0; } @@ -380,7 +379,7 @@ namespace IKVM.Reflection.Emit ExceptionBlock block = exceptionStack.Pop(); if (exceptionBlockAssistanceMode == EBAM_COMPAT || (exceptionBlockAssistanceMode == EBAM_CLEVER && stackHeight != -1)) { - if (block.filterOffset != 0 || (block.exceptionType != MarkerType.Finally && block.exceptionType != MarkerType.Fault)) + if (block.kind != ExceptionHandlingClauseOptions.Finally && block.kind != ExceptionHandlingClauseOptions.Fault) { Emit(OpCodes.Leave, block.labelEnd); } @@ -427,7 +426,7 @@ namespace IKVM.Reflection.Emit public LocalBuilder __DeclareLocal(Type localType, bool pinned, CustomModifiers customModifiers) { - LocalBuilder local = new LocalBuilder(localType, localsCount++, pinned); + LocalBuilder local = new LocalBuilder(localType, localsCount++, pinned, customModifiers); locals.__AddArgument(localType, pinned, customModifiers); if (scope != null) { @@ -494,7 +493,7 @@ namespace IKVM.Reflection.Emit public void Emit(OpCode opc, FieldInfo field) { Emit(opc); - WriteToken(moduleBuilder.GetFieldToken(field)); + WriteToken(moduleBuilder.GetFieldToken(field).Token); } public void Emit(OpCode opc, short arg) @@ -671,22 +670,13 @@ namespace IKVM.Reflection.Emit } } - private void WriteToken(FieldToken token) - { - if (token.IsPseudoToken) - { - tokenFixups.Add(code.Position); - } - code.Write(token.Token); - } - - private void WriteToken(MethodToken token) + private void WriteToken(int token) { - if (token.IsPseudoToken) + if (ModuleBuilder.IsPseudoToken(token)) { tokenFixups.Add(code.Position); } - code.Write(token.Token); + code.Write(token); } private void UpdateStack(OpCode opc, bool hasthis, Type returnType, int parameterCount) @@ -718,7 +708,7 @@ namespace IKVM.Reflection.Emit { UpdateStack(opc, method.HasThis, method.ReturnType, method.ParameterCount); Emit(opc); - WriteToken(moduleBuilder.GetMethodTokenForIL(method)); + WriteToken(moduleBuilder.GetMethodTokenForIL(method).Token); } public void Emit(OpCode opc, ConstructorInfo constructor) @@ -928,7 +918,11 @@ namespace IKVM.Reflection.Emit } else { - rva = WriteFatHeaderAndCode(bb, ref localVarSigTok, initLocals); + if (localsCount != 0) + { + localVarSigTok = moduleBuilder.GetSignatureToken(locals).Token; + } + rva = WriteFatHeaderAndCode(bb, localVarSigTok, initLocals); } if (moduleBuilder.symbolWriter != null) @@ -995,26 +989,23 @@ namespace IKVM.Reflection.Emit } } - private int WriteTinyHeaderAndCode(ByteBuffer bb) + internal static void WriteTinyHeader(ByteBuffer bb, int length) { - int rva = bb.Position; const byte CorILMethod_TinyFormat = 0x2; - bb.Write((byte)(CorILMethod_TinyFormat | (code.Length << 2))); - WriteCode(bb); - return rva; + bb.Write((byte)(CorILMethod_TinyFormat | (length << 2))); } - private int WriteFatHeaderAndCode(ByteBuffer bb, ref int localVarSigTok, bool initLocals) + private int WriteTinyHeaderAndCode(ByteBuffer bb) { - // fat headers require 4-byte alignment - bb.Align(4); int rva = bb.Position; + WriteTinyHeader(bb, code.Length); + AddTokenFixups(bb.Position, moduleBuilder.tokenFixupOffsets, tokenFixups); + bb.Write(code); + return rva; + } - if (localsCount != 0) - { - localVarSigTok = moduleBuilder.GetSignatureToken(locals).Token; - } - + internal static void WriteFatHeader(ByteBuffer bb, bool initLocals, bool exceptions, ushort maxStack, int codeLength, int localVarSigTok) + { const byte CorILMethod_FatFormat = 0x03; const byte CorILMethod_MoreSects = 0x08; const byte CorILMethod_InitLocals = 0x10; @@ -1025,23 +1016,44 @@ namespace IKVM.Reflection.Emit flagsAndSize |= CorILMethod_InitLocals; } - if (exceptions.Count > 0) + if (exceptions) { flagsAndSize |= CorILMethod_MoreSects; } bb.Write(flagsAndSize); bb.Write(maxStack); - bb.Write(code.Length); + bb.Write(codeLength); bb.Write(localVarSigTok); + } - WriteCode(bb); - + private int WriteFatHeaderAndCode(ByteBuffer bb, int localVarSigTok, bool initLocals) + { + // fat headers require 4-byte alignment + bb.Align(4); + int rva = bb.Position; + WriteFatHeader(bb, initLocals, exceptions.Count > 0, maxStack, code.Length, localVarSigTok); + AddTokenFixups(bb.Position, moduleBuilder.tokenFixupOffsets, tokenFixups); + bb.Write(code); if (exceptions.Count > 0) { - bb.Align(4); + exceptions.Sort(exceptions[0]); + WriteExceptionHandlers(bb, exceptions); + } + return rva; + } - bool fat = false; + internal static void WriteExceptionHandlers(ByteBuffer bb, List exceptions) + { + bb.Align(4); + + bool fat = false; + if (exceptions.Count * 12 + 4 > 255) + { + fat = true; + } + else + { foreach (ExceptionBlock block in exceptions) { if (block.tryOffset > 65535 || block.tryLength > 255 || block.handlerOffset > 65535 || block.handlerLength > 255) @@ -1050,105 +1062,50 @@ namespace IKVM.Reflection.Emit break; } } - exceptions.Sort(exceptions[0]); - if (exceptions.Count * 12 + 4 > 255) - { - fat = true; - } - const byte CorILMethod_Sect_EHTable = 0x1; - const byte CorILMethod_Sect_FatFormat = 0x40; - const short COR_ILEXCEPTION_CLAUSE_EXCEPTION = 0x0000; - const short COR_ILEXCEPTION_CLAUSE_FILTER = 0x0001; - const short COR_ILEXCEPTION_CLAUSE_FINALLY = 0x0002; - const short COR_ILEXCEPTION_CLAUSE_FAULT = 0x0004; - - if (fat) + } + + const byte CorILMethod_Sect_EHTable = 0x1; + const byte CorILMethod_Sect_FatFormat = 0x40; + + if (fat) + { + bb.Write((byte)(CorILMethod_Sect_EHTable | CorILMethod_Sect_FatFormat)); + int dataSize = exceptions.Count * 24 + 4; + bb.Write((byte)dataSize); + bb.Write((short)(dataSize >> 8)); + foreach (ExceptionBlock block in exceptions) { - bb.Write((byte)(CorILMethod_Sect_EHTable | CorILMethod_Sect_FatFormat)); - int dataSize = exceptions.Count * 24 + 4; - bb.Write((byte)dataSize); - bb.Write((short)(dataSize >> 8)); - foreach (ExceptionBlock block in exceptions) - { - if (block.exceptionType == MarkerType.Fault) - { - bb.Write((int)COR_ILEXCEPTION_CLAUSE_FAULT); - } - else if (block.exceptionType == MarkerType.Filter) - { - bb.Write((int)COR_ILEXCEPTION_CLAUSE_FILTER); - } - else if (block.exceptionType == MarkerType.Finally) - { - bb.Write((int)COR_ILEXCEPTION_CLAUSE_FINALLY); - } - else - { - bb.Write((int)COR_ILEXCEPTION_CLAUSE_EXCEPTION); - } - bb.Write(block.tryOffset); - bb.Write(block.tryLength); - bb.Write(block.handlerOffset); - bb.Write(block.handlerLength); - if (block.exceptionType != MarkerType.Fault && block.exceptionType != MarkerType.Filter && block.exceptionType != MarkerType.Finally) - { - bb.Write(moduleBuilder.GetTypeTokenForMemberRef(block.exceptionType)); - } - else - { - bb.Write(block.filterOffset); - } - } + bb.Write((int)block.kind); + bb.Write(block.tryOffset); + bb.Write(block.tryLength); + bb.Write(block.handlerOffset); + bb.Write(block.handlerLength); + bb.Write(block.filterOffsetOrExceptionTypeToken); } - else + } + else + { + bb.Write(CorILMethod_Sect_EHTable); + bb.Write((byte)(exceptions.Count * 12 + 4)); + bb.Write((short)0); + foreach (ExceptionBlock block in exceptions) { - bb.Write(CorILMethod_Sect_EHTable); - bb.Write((byte)(exceptions.Count * 12 + 4)); - bb.Write((short)0); - foreach (ExceptionBlock block in exceptions) - { - if (block.exceptionType == MarkerType.Fault) - { - bb.Write(COR_ILEXCEPTION_CLAUSE_FAULT); - } - else if (block.exceptionType == MarkerType.Filter) - { - bb.Write(COR_ILEXCEPTION_CLAUSE_FILTER); - } - else if (block.exceptionType == MarkerType.Finally) - { - bb.Write(COR_ILEXCEPTION_CLAUSE_FINALLY); - } - else - { - bb.Write(COR_ILEXCEPTION_CLAUSE_EXCEPTION); - } - bb.Write((short)block.tryOffset); - bb.Write((byte)block.tryLength); - bb.Write((short)block.handlerOffset); - bb.Write((byte)block.handlerLength); - if (block.exceptionType != MarkerType.Fault && block.exceptionType != MarkerType.Filter && block.exceptionType != MarkerType.Finally) - { - bb.Write(moduleBuilder.GetTypeTokenForMemberRef(block.exceptionType)); - } - else - { - bb.Write(block.filterOffset); - } - } + bb.Write((short)block.kind); + bb.Write((short)block.tryOffset); + bb.Write((byte)block.tryLength); + bb.Write((short)block.handlerOffset); + bb.Write((byte)block.handlerLength); + bb.Write(block.filterOffsetOrExceptionTypeToken); } } - return rva; } - private void WriteCode(ByteBuffer bb) + internal static void AddTokenFixups(int codeOffset, List tokenFixupOffsets, IEnumerable tokenFixups) { - int codeOffset = bb.Position; - foreach (int fixup in this.tokenFixups) + foreach (int fixup in tokenFixups) { - moduleBuilder.tokenFixupOffsets.Add(fixup + codeOffset); + tokenFixupOffsets.Add(fixup + codeOffset); } - bb.Write(code); } private void WriteScope(Scope scope, int localVarSigTok) diff --git a/mcs/class/IKVM.Reflection/Emit/MethodBuilder.cs b/mcs/class/IKVM.Reflection/Emit/MethodBuilder.cs index 89778acdb47..486e74c91ad 100644 --- a/mcs/class/IKVM.Reflection/Emit/MethodBuilder.cs +++ b/mcs/class/IKVM.Reflection/Emit/MethodBuilder.cs @@ -367,6 +367,10 @@ namespace IKVM.Reflection.Emit public GenericTypeParameterBuilder[] DefineGenericParameters(params string[] names) { CheckSig(); + if (gtpb != null) + { + throw new InvalidOperationException("Generic parameters already defined."); + } gtpb = new GenericTypeParameterBuilder[names.Length]; for (int i = 0; i < names.Length; i++) { @@ -622,6 +626,54 @@ namespace IKVM.Reflection.Emit this.ModuleBuilder.AddUnmanagedExport(name, ordinal, this, new RelativeVirtualAddress(0xFFFFFFFF)); } + public void CreateMethodBody(byte[] il, int count) + { + if (il == null) + { + throw new NotSupportedException(); + } + if (il.Length != count) + { + Array.Resize(ref il, count); + } + SetMethodBody(il, 16, null, null, null); + } + + public void SetMethodBody(byte[] il, int maxStack, byte[] localSignature, IEnumerable exceptionHandlers, IEnumerable tokenFixups) + { + ByteBuffer bb = this.ModuleBuilder.methodBodies; + + if (localSignature == null && exceptionHandlers == null && maxStack <= 8 && il.Length < 64) + { + rva = bb.Position; + ILGenerator.WriteTinyHeader(bb, il.Length); + } + else + { + // fat headers require 4-byte alignment + bb.Align(4); + rva = bb.Position; + ILGenerator.WriteFatHeader(bb, initLocals, exceptionHandlers != null, (ushort)maxStack, il.Length, + localSignature == null ? 0 : this.ModuleBuilder.GetSignatureToken(localSignature, localSignature.Length).Token); + } + + if (tokenFixups != null) + { + ILGenerator.AddTokenFixups(bb.Position, this.ModuleBuilder.tokenFixupOffsets, tokenFixups); + } + bb.Write(il); + + if (exceptionHandlers != null) + { + List exceptions = new List(); + foreach (ExceptionHandler block in exceptionHandlers) + { + exceptions.Add(new ILGenerator.ExceptionBlock(block)); + } + ILGenerator.WriteExceptionHandlers(bb, exceptions); + } + } + internal void Bake() { this.nameIndex = this.ModuleBuilder.Strings.Add(name); diff --git a/mcs/class/IKVM.Reflection/Emit/ModuleBuilder.cs b/mcs/class/IKVM.Reflection/Emit/ModuleBuilder.cs index 8ffe17ba957..7a64f248a19 100644 --- a/mcs/class/IKVM.Reflection/Emit/ModuleBuilder.cs +++ b/mcs/class/IKVM.Reflection/Emit/ModuleBuilder.cs @@ -401,7 +401,6 @@ namespace IKVM.Reflection.Emit private int ExportType(Type type) { ExportedTypeTable.Record rec = new ExportedTypeTable.Record(); - rec.TypeDefId = type.MetadataToken; rec.TypeName = this.Strings.Add(type.__Name); string ns = type.__Namespace; rec.TypeNamespace = ns == null ? 0 : this.Strings.Add(ns); @@ -492,13 +491,13 @@ namespace IKVM.Reflection.Emit ByteBuffer namedArgs = new ByteBuffer(100); ByteBuffer bb = new ByteBuffer(list.Count * 100); bb.Write((byte)'.'); - bb.WriteCompressedInt(list.Count); + bb.WriteCompressedUInt(list.Count); foreach (CustomAttributeBuilder cab in list) { bb.Write(cab.Constructor.DeclaringType.AssemblyQualifiedName); namedArgs.Clear(); cab.WriteNamedArgumentsForDeclSecurity(this, namedArgs); - bb.WriteCompressedInt(namedArgs.Length); + bb.WriteCompressedUInt(namedArgs.Length); bb.Write(namedArgs); } return this.Blobs.Add(bb); @@ -920,7 +919,7 @@ namespace IKVM.Reflection.Emit resolvedTokens[index] = realToken; } - internal bool IsPseudoToken(int token) + internal static bool IsPseudoToken(int token) { return token < 0; } diff --git a/mcs/class/IKVM.Reflection/Emit/PropertyBuilder.cs b/mcs/class/IKVM.Reflection/Emit/PropertyBuilder.cs index 2900f7abb5f..6e3c741c8fa 100644 --- a/mcs/class/IKVM.Reflection/Emit/PropertyBuilder.cs +++ b/mcs/class/IKVM.Reflection/Emit/PropertyBuilder.cs @@ -275,7 +275,7 @@ namespace IKVM.Reflection.Emit internal override int GetCurrentToken() { - if (typeBuilder.ModuleBuilder.IsSaved && typeBuilder.ModuleBuilder.IsPseudoToken(lazyPseudoToken)) + if (typeBuilder.ModuleBuilder.IsSaved && ModuleBuilder.IsPseudoToken(lazyPseudoToken)) { return typeBuilder.ModuleBuilder.ResolvePseudoToken(lazyPseudoToken); } diff --git a/mcs/class/IKVM.Reflection/Emit/SignatureHelper.cs b/mcs/class/IKVM.Reflection/Emit/SignatureHelper.cs index b70ace82169..64dc18d2804 100644 --- a/mcs/class/IKVM.Reflection/Emit/SignatureHelper.cs +++ b/mcs/class/IKVM.Reflection/Emit/SignatureHelper.cs @@ -115,8 +115,8 @@ namespace IKVM.Reflection.Emit if (type != Signature.FIELD) { bb.Position = 1; - bb.Insert(MetadataWriter.GetCompressedIntLength(paramCount) - bb.GetCompressedIntLength()); - bb.WriteCompressedInt(paramCount); + bb.Insert(MetadataWriter.GetCompressedUIntLength(paramCount) - bb.GetCompressedUIntLength()); + bb.WriteCompressedUInt(paramCount); } return bb; } diff --git a/mcs/class/IKVM.Reflection/Emit/Tokens.cs b/mcs/class/IKVM.Reflection/Emit/Tokens.cs index 49ac4c6adb9..9b39f29c8ef 100644 --- a/mcs/class/IKVM.Reflection/Emit/Tokens.cs +++ b/mcs/class/IKVM.Reflection/Emit/Tokens.cs @@ -75,11 +75,6 @@ namespace IKVM.Reflection.Emit this.token = token; } - internal bool IsPseudoToken - { - get { return token < 0; } - } - public int Token { get { return token; } @@ -121,11 +116,6 @@ namespace IKVM.Reflection.Emit this.token = token; } - internal bool IsPseudoToken - { - get { return token < 0; } - } - public int Token { get { return token; } diff --git a/mcs/class/IKVM.Reflection/Emit/TypeBuilder.cs b/mcs/class/IKVM.Reflection/Emit/TypeBuilder.cs index b9f2a8f4b78..aa6d2642907 100644 --- a/mcs/class/IKVM.Reflection/Emit/TypeBuilder.cs +++ b/mcs/class/IKVM.Reflection/Emit/TypeBuilder.cs @@ -397,6 +397,11 @@ namespace IKVM.Reflection.Emit return DefineProperty(name, attributes, returnType, null, null, parameterTypes, null, null); } + public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) + { + return DefineProperty(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null); + } + public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) { @@ -481,7 +486,7 @@ namespace IKVM.Reflection.Emit return DefineNestedType(name, attr, parent, packSize, 0); } - private TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, PackingSize packSize, int typeSize) + public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, PackingSize packSize, int typeSize) { string ns = null; int lastdot = name.LastIndexOf('.'); @@ -689,7 +694,7 @@ namespace IKVM.Reflection.Emit return this; } - public Type CreateType() + public TypeInfo CreateTypeInfo() { if ((typeFlags & TypeFlags.Baked) != 0) { @@ -711,7 +716,7 @@ namespace IKVM.Reflection.Emit hasConstructor |= mb.IsSpecialName && mb.Name == ConstructorInfo.ConstructorName; mb.Bake(); } - if (!hasConstructor && !IsModulePseudoType && !IsInterface && !IsValueType && !(IsAbstract && IsSealed)) + if (!hasConstructor && !IsModulePseudoType && !IsInterface && !IsValueType && !(IsAbstract && IsSealed) && Universe.AutomaticallyProvideDefaultConstructor) { ((MethodBuilder)DefineDefaultConstructor(MethodAttributes.Public).GetMethodInfo()).Bake(); } @@ -740,6 +745,11 @@ namespace IKVM.Reflection.Emit return new BakedType(this); } + public Type CreateType() + { + return CreateTypeInfo(); + } + internal void PopulatePropertyAndEventTables() { if (properties != null) diff --git a/mcs/class/IKVM.Reflection/Enums.cs b/mcs/class/IKVM.Reflection/Enums.cs index 2ff8de990bd..9fcbb6d0433 100644 --- a/mcs/class/IKVM.Reflection/Enums.cs +++ b/mcs/class/IKVM.Reflection/Enums.cs @@ -222,7 +222,8 @@ namespace IKVM.Reflection IA64 = 3, Amd64 = 4, Arm = 5, - // if an item is added here, make sure to update AssemblyName.ProcessorArchitecture and Fusion.ParseAssemblyName as well + // if an item is added here, make sure to update AssemblyName.ProcessorArchitecture, + // AssemblyReader.GetNameImpl() and Fusion.ParseAssemblyName as well } [Flags] diff --git a/mcs/class/IKVM.Reflection/EventInfo.cs b/mcs/class/IKVM.Reflection/EventInfo.cs index ffd9a0df32d..d8f3c03a4be 100644 --- a/mcs/class/IKVM.Reflection/EventInfo.cs +++ b/mcs/class/IKVM.Reflection/EventInfo.cs @@ -74,6 +74,21 @@ namespace IKVM.Reflection return GetOtherMethods(false); } + public MethodInfo AddMethod + { + get { return GetAddMethod(true); } + } + + public MethodInfo RaiseMethod + { + get { return GetRaiseMethod(true); } + } + + public MethodInfo RemoveMethod + { + get { return GetRemoveMethod(true); } + } + internal virtual EventInfo BindTypeParameters(Type type) { return new GenericEventInfo(this.DeclaringType.BindTypeParameters(type), this); diff --git a/mcs/class/IKVM.Reflection/Fusion.cs b/mcs/class/IKVM.Reflection/Fusion.cs index d9c0e086110..0d0f8ec14cb 100644 --- a/mcs/class/IKVM.Reflection/Fusion.cs +++ b/mcs/class/IKVM.Reflection/Fusion.cs @@ -510,14 +510,7 @@ namespace IKVM.Reflection publicKeyToken = null; return false; } - // HACK use AssemblyName to convert PublicKey to PublicKeyToken - byte[] token = new System.Reflection.AssemblyName("Foo, PublicKey=" + str).GetPublicKeyToken(); - StringBuilder sb = new StringBuilder(token.Length * 2); - for (int i = 0; i < token.Length; i++) - { - sb.AppendFormat("{0:x2}", token[i]); - } - publicKeyToken = sb.ToString(); + publicKeyToken = AssemblyName.ComputePublicKeyToken(str); return true; } diff --git a/mcs/class/IKVM.Reflection/IKVM.Reflection.csproj b/mcs/class/IKVM.Reflection/IKVM.Reflection.csproj index e7e7ad30cf2..540e037beda 100644 --- a/mcs/class/IKVM.Reflection/IKVM.Reflection.csproj +++ b/mcs/class/IKVM.Reflection/IKVM.Reflection.csproj @@ -58,6 +58,7 @@ + @@ -100,6 +101,7 @@ + @@ -116,6 +118,7 @@ + @@ -130,6 +133,7 @@ +