提交 82579609 编写于 作者: M Marek Safar

Add IKVM.Reflection

上级 69549731
/*
Copyright (C) 2009 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.Runtime.Serialization;
namespace IKVM.Reflection
{
[Serializable]
public sealed class AmbiguousMatchException : Exception
{
public AmbiguousMatchException()
{
}
public AmbiguousMatchException(string message)
: base(message)
{
}
public AmbiguousMatchException(string message, Exception inner)
: base(message, inner)
{
}
private AmbiguousMatchException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
}
/*
Copyright (C) 2009 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
{
public abstract class Assembly : ICustomAttributeProvider
{
internal readonly Universe universe;
internal Assembly(Universe universe)
{
this.universe = universe;
}
public abstract Type[] GetTypes();
public abstract string FullName { get; }
public abstract AssemblyName GetName();
public abstract string ImageRuntimeVersion { get; }
public abstract Module ManifestModule { get; }
public abstract MethodInfo EntryPoint { get; }
public abstract string Location { get; }
public abstract AssemblyName[] GetReferencedAssemblies();
public abstract Module[] GetModules(bool getResourceModules);
public abstract Module[] GetLoadedModules(bool getResourceModules);
public abstract Module GetModule(string name);
public abstract string[] GetManifestResourceNames();
public abstract ManifestResourceInfo GetManifestResourceInfo(string resourceName);
public abstract System.IO.Stream GetManifestResourceStream(string resourceName);
internal abstract Type GetTypeImpl(string typeName);
public Module[] GetModules()
{
return GetModules(true);
}
public Module[] GetLoadedModules()
{
return GetLoadedModules(true);
}
public AssemblyName GetName(bool copiedName)
{
return GetName();
}
public bool ReflectionOnly
{
get { return true; }
}
public Type[] GetExportedTypes()
{
List<Type> list = new List<Type>();
foreach (Type type in GetTypes())
{
if (type.IsVisible)
{
list.Add(type);
}
}
return list.ToArray();
}
public Type GetType(string typeName)
{
return GetType(typeName, false);
}
public Type GetType(string typeName, bool throwOnError)
{
TypeNameParser parser = TypeNameParser.Parse(typeName, throwOnError);
if (parser.Error)
{
return null;
}
if (parser.AssemblyName != null)
{
if (throwOnError)
{
throw new ArgumentException("Type names passed to Assembly.GetType() must not specify an assembly.");
}
else
{
return null;
}
}
return parser.Expand(GetTypeImpl(parser.FirstNamePart), this, throwOnError, typeName);
}
public virtual Module LoadModule(string moduleName, byte[] rawModule)
{
throw new NotSupportedException();
}
public Module LoadModule(string moduleName, byte[] rawModule, byte[] rawSymbolStore)
{
return LoadModule(moduleName, rawModule);
}
public bool IsDefined(Type attributeType, bool inherit)
{
return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit).Count != 0;
}
public IList<CustomAttributeData> __GetCustomAttributes(Type attributeType, bool inherit)
{
return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit);
}
public static string CreateQualifiedName(string assemblyName, string typeName)
{
return assemblyName == null ? typeName : typeName + ", " + assemblyName;
}
public static Assembly GetAssembly(Type type)
{
return type.Assembly;
}
public string CodeBase
{
get
{
string path = this.Location.Replace(System.IO.Path.DirectorySeparatorChar, '/');
if (!path.StartsWith("/"))
{
path = "/" + path;
}
return "file://" + path;
}
}
internal abstract IList<CustomAttributeData> GetCustomAttributesData(Type attributeType);
}
}
/*
Copyright (C) 2009 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.Globalization;
using System.Configuration.Assemblies;
using System.IO;
using IKVM.Reflection.Reader;
namespace IKVM.Reflection
{
public sealed class AssemblyName : ICloneable
{
private readonly System.Reflection.AssemblyName name;
private string culture;
private AssemblyName(System.Reflection.AssemblyName name, string culture)
{
this.name = name;
this.culture = culture;
}
public AssemblyName()
{
name = new System.Reflection.AssemblyName();
}
public AssemblyName(string assemblyName)
{
name = new System.Reflection.AssemblyName(assemblyName);
}
public override string ToString()
{
string str = name.ToString();
if (culture != null)
{
str = str.Replace("Culture=neutral", "Culture=" + culture);
}
return str;
}
public string Name
{
get { return name.Name; }
set { name.Name = value; }
}
public CultureInfo CultureInfo
{
get { return name.CultureInfo; }
set
{
name.CultureInfo = value;
culture = null;
}
}
internal string Culture
{
set
{
culture = value;
name.CultureInfo = CultureInfo.InvariantCulture;
}
}
public Version Version
{
get { return name.Version; }
set { name.Version = value; }
}
public StrongNameKeyPair KeyPair
{
get { return name.KeyPair == null ? null : new StrongNameKeyPair(name.KeyPair); }
set { name.KeyPair = value == null ? null : value.keyPair; }
}
public string CodeBase
{
get { return name.CodeBase; }
set { name.CodeBase = value; }
}
public ProcessorArchitecture ProcessorArchitecture
{
get { return (ProcessorArchitecture)name.ProcessorArchitecture; }
set { name.ProcessorArchitecture = (System.Reflection.ProcessorArchitecture)value; }
}
public AssemblyNameFlags Flags
{
get { return (AssemblyNameFlags)name.Flags; }
set { name.Flags = (System.Reflection.AssemblyNameFlags)value; }
}
public AssemblyVersionCompatibility VersionCompatibility
{
get { return name.VersionCompatibility; }
set { name.VersionCompatibility = value; }
}
public byte[] GetPublicKey()
{
return name.GetPublicKey();
}
public void SetPublicKey(byte[] publicKey)
{
name.SetPublicKey(publicKey);
}
public byte[] GetPublicKeyToken()
{
return name.GetPublicKeyToken();
}
public void SetPublicKeyToken(byte[] publicKeyToken)
{
name.SetPublicKeyToken(publicKeyToken);
}
public AssemblyHashAlgorithm HashAlgorithm
{
get { return name.HashAlgorithm; }
set { name.HashAlgorithm = value; }
}
public string FullName
{
get
{
string str = name.FullName;
if (culture != null)
{
str = str.Replace("Culture=neutral", "Culture=" + culture);
}
return str;
}
}
public override bool Equals(object obj)
{
AssemblyName other = obj as AssemblyName;
return other != null && other.FullName == this.FullName;
}
public override int GetHashCode()
{
return FullName.GetHashCode();
}
public object Clone()
{
return new AssemblyName((System.Reflection.AssemblyName)name.Clone(), culture);
}
public static bool ReferenceMatchesDefinition(AssemblyName reference, AssemblyName definition)
{
return System.Reflection.AssemblyName.ReferenceMatchesDefinition(reference.name, definition.name);
}
public static AssemblyName GetAssemblyName(string path)
{
try
{
path = Path.GetFullPath(path);
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
ModuleReader module = new ModuleReader(null, null, fs, path);
if (module.Assembly == null)
{
throw new BadImageFormatException("Module does not contain a manifest");
}
return module.Assembly.GetName();
}
}
catch (IOException x)
{
throw new FileNotFoundException(x.Message, x);
}
catch (UnauthorizedAccessException x)
{
throw new FileNotFoundException(x.Message, x);
}
}
}
}
/*
Copyright (C) 2009 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.Runtime.Serialization;
namespace IKVM.Reflection
{
[Serializable]
public sealed class BadImageFormatException : Exception
{
public BadImageFormatException()
{
}
public BadImageFormatException(string message)
: base(message)
{
}
public BadImageFormatException(string message, Exception inner)
: base(message, inner)
{
}
private BadImageFormatException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
}
/*
Copyright (C) 2010 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.Globalization;
namespace IKVM.Reflection
{
public abstract class Binder
{
protected Binder()
{
throw new NotSupportedException();
}
public abstract MethodBase BindToMethod(BindingFlags bindingAttr, MethodBase[] match, ref object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] names, out object state);
public abstract FieldInfo BindToField(BindingFlags bindingAttr, FieldInfo[] match, object value, CultureInfo culture);
public abstract object ChangeType(object value, Type type, CultureInfo culture);
public abstract void ReorderArgumentArray(ref object[] args, object state);
public abstract MethodBase SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers);
public abstract PropertyInfo SelectProperty(BindingFlags bindingAttr, PropertyInfo[] match, Type returnType, Type[] indexes, ParameterModifier[] modifiers);
}
}
/*
Copyright (C) 2009 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
{
public abstract class ConstructorInfo : MethodBase
{
public static readonly string ConstructorName = ".ctor";
public static readonly string TypeConstructorName = ".cctor";
internal abstract MethodInfo GetMethodInfo();
internal override MethodBase BindTypeParameters(Type type)
{
return new ConstructorInfoImpl((MethodInfo)GetMethodInfo().BindTypeParameters(type));
}
public sealed override MemberTypes MemberType
{
get { return MemberTypes.Constructor; }
}
public override bool ContainsGenericParameters
{
get { return GetMethodInfo().ContainsGenericParameters; }
}
public sealed override ParameterInfo[] GetParameters()
{
ParameterInfo[] parameters = GetMethodInfo().GetParameters();
for (int i = 0; i < parameters.Length; i++)
{
parameters[i] = new ParameterInfoWrapper(this, parameters[i]);
}
return parameters;
}
private sealed class ParameterInfoWrapper : ParameterInfo
{
private readonly ConstructorInfo ctor;
private readonly ParameterInfo forward;
internal ParameterInfoWrapper(ConstructorInfo ctor, ParameterInfo forward)
{
this.ctor = ctor;
this.forward = forward;
}
public override string Name
{
get { return forward.Name; }
}
public override Type ParameterType
{
get { return forward.ParameterType; }
}
public override ParameterAttributes Attributes
{
get { return forward.Attributes; }
}
public override int Position
{
get { return forward.Position; }
}
public override object RawDefaultValue
{
get { return forward.RawDefaultValue; }
}
public override Type[] GetOptionalCustomModifiers()
{
return forward.GetOptionalCustomModifiers();
}
public override Type[] GetRequiredCustomModifiers()
{
return forward.GetRequiredCustomModifiers();
}
public override MemberInfo Member
{
get { return ctor; }
}
public override int MetadataToken
{
get { return forward.MetadataToken; }
}
internal override Module Module
{
get { return ctor.Module; }
}
internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
{
return forward.GetCustomAttributesData(attributeType);
}
}
}
sealed class ConstructorInfoImpl : ConstructorInfo
{
private readonly MethodInfo method;
internal ConstructorInfoImpl(MethodInfo method)
{
this.method = method;
}
public override bool Equals(object obj)
{
ConstructorInfoImpl other = obj as ConstructorInfoImpl;
return other != null && other.method.Equals(method);
}
public override int GetHashCode()
{
return method.GetHashCode();
}
public override MethodBody GetMethodBody()
{
return method.GetMethodBody();
}
public override CallingConventions CallingConvention
{
get { return method.CallingConvention; }
}
public override MethodAttributes Attributes
{
get { return method.Attributes; }
}
public override MethodImplAttributes GetMethodImplementationFlags()
{
return method.GetMethodImplementationFlags();
}
internal override int ParameterCount
{
get { return method.ParameterCount; }
}
public override Type DeclaringType
{
get { return method.DeclaringType; }
}
public override string Name
{
get { return method.Name; }
}
public override string ToString()
{
return method.ToString();
}
public override Module Module
{
get { return method.Module; }
}
public override int MetadataToken
{
get { return method.MetadataToken; }
}
internal override MethodInfo GetMethodInfo()
{
return method;
}
internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
{
return method.GetCustomAttributesData(attributeType);
}
internal override MethodInfo GetMethodOnTypeDefinition()
{
return method.GetMethodOnTypeDefinition();
}
internal override MethodSignature MethodSignature
{
get { return method.MethodSignature; }
}
internal override int ImportTo(Emit.ModuleBuilder module)
{
return method.ImportTo(module);
}
}
}
/*
Copyright (C) 2009-2010 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;
using System.Text;
using System.IO;
using IKVM.Reflection.Reader;
using IKVM.Reflection.Emit;
using IKVM.Reflection.Metadata;
namespace IKVM.Reflection
{
public sealed class CustomAttributeData
{
internal static readonly IList<CustomAttributeData> EmptyList = new List<CustomAttributeData>(0).AsReadOnly();
private Module module;
private int index;
private ConstructorInfo lazyConstructor;
private IList<CustomAttributeTypedArgument> lazyConstructorArguments;
private IList<CustomAttributeNamedArgument> lazyNamedArguments;
internal CustomAttributeData(Module module, int index)
{
this.module = module;
this.index = index;
}
internal CustomAttributeData(ConstructorInfo constructor, object[] args, List<CustomAttributeNamedArgument> namedArguments)
{
this.lazyConstructor = constructor;
MethodSignature sig = constructor.MethodSignature;
List<CustomAttributeTypedArgument> list = new List<CustomAttributeTypedArgument>();
for (int i = 0; i < args.Length; i++)
{
list.Add(new CustomAttributeTypedArgument(sig.GetParameterType(i), args[i]));
}
lazyConstructorArguments = list.AsReadOnly();
if (namedArguments == null)
{
this.lazyNamedArguments = Empty<CustomAttributeNamedArgument>.Array;
}
else
{
this.lazyNamedArguments = namedArguments.AsReadOnly();
}
}
internal CustomAttributeData(Assembly asm, ConstructorInfo constructor, ByteReader br)
{
this.lazyConstructor = constructor;
if (br.Length == 0)
{
// it's legal to have an empty blob
lazyConstructorArguments = Empty<CustomAttributeTypedArgument>.Array;
lazyNamedArguments = Empty<CustomAttributeNamedArgument>.Array;
}
else
{
if (br.ReadUInt16() != 1)
{
throw new BadImageFormatException();
}
lazyConstructorArguments = ReadConstructorArguments(asm, br, constructor);
lazyNamedArguments = ReadNamedArguments(asm, br, br.ReadUInt16(), constructor.DeclaringType);
}
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append('[');
sb.Append(Constructor.DeclaringType.FullName);
sb.Append('(');
string sep = "";
foreach (CustomAttributeTypedArgument arg in ConstructorArguments)
{
sb.Append(sep);
sep = ", ";
AppendValue(sb, arg);
}
foreach (CustomAttributeNamedArgument named in NamedArguments)
{
sb.Append(sep);
sep = ", ";
sb.Append(named.MemberInfo.Name);
sb.Append(" = ");
AppendValue(sb, named.TypedValue);
}
sb.Append(')');
sb.Append(']');
return sb.ToString();
}
private static void AppendValue(StringBuilder sb, CustomAttributeTypedArgument arg)
{
if (arg.ArgumentType == arg.ArgumentType.Module.universe.System_String)
{
sb.Append('"').Append(arg.Value).Append('"');
}
else
{
if (arg.ArgumentType.IsEnum)
{
sb.Append('(');
sb.Append(arg.ArgumentType.FullName);
sb.Append(')');
}
sb.Append(arg.Value);
}
}
internal static void ReadDeclarativeSecurity(Assembly asm, List<CustomAttributeData> list, int action, ByteReader br)
{
Universe u = asm.universe;
if (br.PeekByte() == '.')
{
br.ReadByte();
int count = br.ReadCompressedInt();
for (int j = 0; j < count; j++)
{
Type type = ReadType(asm, br);
ConstructorInfo constructor;
if (type == u.System_Security_Permissions_HostProtectionAttribute && action == (int)System.Security.Permissions.SecurityAction.LinkDemand)
{
constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
}
else
{
constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { u.System_Security_Permissions_SecurityAction }, null);
}
// LAMESPEC there is an additional length here (probably of the named argument list)
ByteReader slice = br.Slice(br.ReadCompressedInt());
// LAMESPEC the count of named arguments is a compressed integer (instead of UInt16 as NumNamed in custom attributes)
list.Add(new CustomAttributeData(constructor, action, ReadNamedArguments(asm, slice, slice.ReadCompressedInt(), type)));
}
}
else
{
// .NET 1.x format (xml)
char[] buf = new char[br.Length / 2];
for (int i = 0; i < buf.Length; i++)
{
buf[i] = br.ReadChar();
}
string xml = new String(buf);
ConstructorInfo constructor = u.System_Security_Permissions_PermissionSetAttribute.GetConstructor(new Type[] { u.System_Security_Permissions_SecurityAction });
List<CustomAttributeNamedArgument> args = new List<CustomAttributeNamedArgument>();
args.Add(new CustomAttributeNamedArgument(u.System_Security_Permissions_PermissionSetAttribute.GetProperty("XML"),
new CustomAttributeTypedArgument(u.System_String, xml)));
list.Add(new CustomAttributeData(constructor, action, args));
}
}
private CustomAttributeData(ConstructorInfo constructor, int securityAction, IList<CustomAttributeNamedArgument> namedArguments)
{
Universe u = constructor.Module.universe;
this.lazyConstructor = constructor;
List<CustomAttributeTypedArgument> list = new List<CustomAttributeTypedArgument>();
list.Add(new CustomAttributeTypedArgument(u.System_Security_Permissions_SecurityAction, securityAction));
this.lazyConstructorArguments = list.AsReadOnly();
this.lazyNamedArguments = namedArguments;
}
private static Type ReadFieldOrPropType(Assembly asm, ByteReader br)
{
Universe u = asm.universe;
switch (br.ReadByte())
{
case Signature.ELEMENT_TYPE_BOOLEAN:
return u.System_Boolean;
case Signature.ELEMENT_TYPE_CHAR:
return u.System_Char;
case Signature.ELEMENT_TYPE_I1:
return u.System_SByte;
case Signature.ELEMENT_TYPE_U1:
return u.System_Byte;
case Signature.ELEMENT_TYPE_I2:
return u.System_Int16;
case Signature.ELEMENT_TYPE_U2:
return u.System_UInt16;
case Signature.ELEMENT_TYPE_I4:
return u.System_Int32;
case Signature.ELEMENT_TYPE_U4:
return u.System_UInt32;
case Signature.ELEMENT_TYPE_I8:
return u.System_Int64;
case Signature.ELEMENT_TYPE_U8:
return u.System_UInt64;
case Signature.ELEMENT_TYPE_R4:
return u.System_Single;
case Signature.ELEMENT_TYPE_R8:
return u.System_Double;
case Signature.ELEMENT_TYPE_STRING:
return u.System_String;
case Signature.ELEMENT_TYPE_SZARRAY:
return ReadFieldOrPropType(asm, br).MakeArrayType();
case 0x55:
return ReadType(asm, br);
case 0x50:
return u.System_Type;
case 0x51:
return u.System_Object;
default:
throw new InvalidOperationException();
}
}
private static CustomAttributeTypedArgument ReadFixedArg(Assembly asm, ByteReader br, Type type)
{
Universe u = asm.universe;
if (type == u.System_String)
{
return new CustomAttributeTypedArgument(type, br.ReadString());
}
else if (type == u.System_Type)
{
return new CustomAttributeTypedArgument(type, ReadType(asm, br));
}
else if (type == u.System_Object)
{
return ReadFixedArg(asm, br, ReadFieldOrPropType(asm, br));
}
else if (type.IsArray)
{
int length = br.ReadInt32();
if (length == -1)
{
return new CustomAttributeTypedArgument(type, null);
}
Type elementType = type.GetElementType();
CustomAttributeTypedArgument[] array = new CustomAttributeTypedArgument[length];
for (int i = 0; i < length; i++)
{
array[i] = ReadFixedArg(asm, br, elementType);
}
return new CustomAttributeTypedArgument(type, array);
}
else if (type.IsEnum)
{
return new CustomAttributeTypedArgument(type, ReadFixedArg(asm, br, type.GetEnumUnderlyingTypeImpl()).Value);
}
else
{
switch (Type.GetTypeCode(type))
{
case TypeCode.Boolean:
return new CustomAttributeTypedArgument(type, br.ReadByte() != 0);
case TypeCode.Char:
return new CustomAttributeTypedArgument(type, br.ReadChar());
case TypeCode.Single:
return new CustomAttributeTypedArgument(type, br.ReadSingle());
case TypeCode.Double:
return new CustomAttributeTypedArgument(type, br.ReadDouble());
case TypeCode.SByte:
return new CustomAttributeTypedArgument(type, br.ReadSByte());
case TypeCode.Int16:
return new CustomAttributeTypedArgument(type, br.ReadInt16());
case TypeCode.Int32:
return new CustomAttributeTypedArgument(type, br.ReadInt32());
case TypeCode.Int64:
return new CustomAttributeTypedArgument(type, br.ReadInt64());
case TypeCode.Byte:
return new CustomAttributeTypedArgument(type, br.ReadByte());
case TypeCode.UInt16:
return new CustomAttributeTypedArgument(type, br.ReadUInt16());
case TypeCode.UInt32:
return new CustomAttributeTypedArgument(type, br.ReadUInt32());
case TypeCode.UInt64:
return new CustomAttributeTypedArgument(type, br.ReadUInt64());
default:
throw new InvalidOperationException();
}
}
}
private static Type ReadType(Assembly asm, ByteReader br)
{
string typeName = br.ReadString();
if (typeName == null)
{
return null;
}
if (typeName.Length > 0 && typeName[typeName.Length - 1] == 0)
{
// there are broken compilers that emit an extra NUL character after the type name
typeName = typeName.Substring(0, typeName.Length - 1);
}
return asm.universe.GetType(asm, typeName, true);
}
private static IList<CustomAttributeTypedArgument> ReadConstructorArguments(Assembly asm, ByteReader br, ConstructorInfo constructor)
{
MethodSignature sig = constructor.MethodSignature;
int count = sig.GetParameterCount();
List<CustomAttributeTypedArgument> list = new List<CustomAttributeTypedArgument>(count);
for (int i = 0; i < count; i++)
{
list.Add(ReadFixedArg(asm, br, sig.GetParameterType(i)));
}
return list.AsReadOnly();
}
private static IList<CustomAttributeNamedArgument> ReadNamedArguments(Assembly asm, ByteReader br, int named, Type type)
{
List<CustomAttributeNamedArgument> list = new List<CustomAttributeNamedArgument>(named);
for (int i = 0; i < named; i++)
{
byte fieldOrProperty = br.ReadByte();
Type fieldOrPropertyType = ReadFieldOrPropType(asm, br);
string name = br.ReadString();
CustomAttributeTypedArgument value = ReadFixedArg(asm, br, fieldOrPropertyType);
MemberInfo member;
switch (fieldOrProperty)
{
case 0x53:
member = GetField(type, name);
break;
case 0x54:
member = GetProperty(type, name);
break;
default:
throw new BadImageFormatException();
}
if (member == null)
{
throw new BadImageFormatException();
}
list.Add(new CustomAttributeNamedArgument(member, value));
}
return list.AsReadOnly();
}
private static FieldInfo GetField(Type type, string name)
{
for (; type != null; type = type.BaseType)
{
foreach (FieldInfo field in type.__GetDeclaredFields())
{
if (field.IsPublic && !field.IsStatic && field.Name == name)
{
return field;
}
}
}
return null;
}
private static PropertyInfo GetProperty(Type type, string name)
{
for (; type != null; type = type.BaseType)
{
foreach (PropertyInfo property in type.__GetDeclaredProperties())
{
if (property.IsPublic && !property.IsStatic && property.Name == name)
{
return property;
}
}
}
return null;
}
public void __ReadTypeName(out string ns, out string name)
{
if (lazyConstructor == null)
{
ModuleReader mod = module as ModuleReader;
if (mod != null)
{
int methodToken = mod.CustomAttribute.records[index].Type;
if ((methodToken >> 24) == MemberRefTable.Index)
{
int methodIndex = (methodToken & 0xFFFFFF) - 1;
int typeToken = mod.MemberRef.records[methodIndex].Class;
if ((typeToken >> 24) == TypeRefTable.Index)
{
int typeIndex = (typeToken & 0xFFFFFF) - 1;
int typeNameSpace = mod.TypeRef.records[typeIndex].TypeNameSpace;
ns = typeNameSpace == 0 ? null : mod.GetString(typeNameSpace);
name = mod.GetString(mod.TypeRef.records[typeIndex].TypeName);
return;
}
}
}
}
ns = Constructor.DeclaringType.Namespace;
name = Constructor.DeclaringType.Name;
}
public ConstructorInfo Constructor
{
get
{
if (lazyConstructor == null)
{
lazyConstructor = (ConstructorInfo)module.ResolveMethod(module.CustomAttribute.records[index].Type);
}
return lazyConstructor;
}
}
public IList<CustomAttributeTypedArgument> ConstructorArguments
{
get
{
if (lazyConstructorArguments == null)
{
LazyParseArguments();
}
return lazyConstructorArguments;
}
}
public IList<CustomAttributeNamedArgument> NamedArguments
{
get
{
if (lazyNamedArguments == null)
{
LazyParseArguments();
}
return lazyNamedArguments;
}
}
private void LazyParseArguments()
{
ByteReader br = module.GetBlob(module.CustomAttribute.records[index].Value);
if (br.Length == 0)
{
// it's legal to have an empty blob
lazyConstructorArguments = Empty<CustomAttributeTypedArgument>.Array;
lazyNamedArguments = Empty<CustomAttributeNamedArgument>.Array;
}
else
{
if (br.ReadUInt16() != 1)
{
throw new BadImageFormatException();
}
lazyConstructorArguments = ReadConstructorArguments(module.Assembly, br, Constructor);
lazyNamedArguments = ReadNamedArguments(module.Assembly, br, br.ReadUInt16(), Constructor.DeclaringType);
}
}
public CustomAttributeBuilder __ToBuilder()
{
object[] args = new object[ConstructorArguments.Count];
for (int i = 0; i < args.Length; i++)
{
args[i] = ConstructorArguments[i].Value;
}
List<PropertyInfo> namedProperties = new List<PropertyInfo>();
List<object> propertyValues = new List<object>();
List<FieldInfo> namedFields = new List<FieldInfo>();
List<object> fieldValues = new List<object>();
foreach (CustomAttributeNamedArgument named in NamedArguments)
{
if (named.MemberInfo is PropertyInfo)
{
namedProperties.Add((PropertyInfo)named.MemberInfo);
propertyValues.Add(named.TypedValue.Value);
}
else
{
namedFields.Add((FieldInfo)named.MemberInfo);
fieldValues.Add(named.TypedValue.Value);
}
}
return new CustomAttributeBuilder(Constructor, args, namedProperties.ToArray(), propertyValues.ToArray(), namedFields.ToArray(), fieldValues.ToArray());
}
public static IList<CustomAttributeData> GetCustomAttributes(MemberInfo member)
{
return member.GetCustomAttributesData(null);
}
public static IList<CustomAttributeData> GetCustomAttributes(Assembly assembly)
{
return assembly.GetCustomAttributesData(null);
}
public static IList<CustomAttributeData> GetCustomAttributes(Module module)
{
return module.GetCustomAttributesData(null);
}
public static IList<CustomAttributeData> GetCustomAttributes(ParameterInfo parameter)
{
return parameter.GetCustomAttributesData(null);
}
public static IList<CustomAttributeData> __GetCustomAttributes(Assembly assembly, Type attributeType, bool inherit)
{
return assembly.GetCustomAttributesData(attributeType);
}
public static IList<CustomAttributeData> __GetCustomAttributes(Module module, Type attributeType, bool inherit)
{
return module.GetCustomAttributesData(attributeType);
}
public static IList<CustomAttributeData> __GetCustomAttributes(ParameterInfo parameter, Type attributeType, bool inherit)
{
return parameter.GetCustomAttributesData(attributeType);
}
public static IList<CustomAttributeData> __GetCustomAttributes(MemberInfo member, Type attributeType, bool inherit)
{
if (!inherit || !IsInheritableAttribute(attributeType))
{
return member.GetCustomAttributesData(attributeType);
}
List<CustomAttributeData> list = new List<CustomAttributeData>();
for (; ; )
{
list.AddRange(member.GetCustomAttributesData(attributeType));
Type type = member as Type;
if (type != null)
{
type = type.BaseType;
if (type == null)
{
return list;
}
member = type;
continue;
}
MethodInfo method = member as MethodInfo;
if (method != null)
{
MemberInfo prev = member;
method = method.GetBaseDefinition();
if (method == null || method == prev)
{
return list;
}
member = method;
continue;
}
return list;
}
}
public static IList<CustomAttributeData> __GetDeclarativeSecurity(Assembly assembly)
{
return assembly.ManifestModule.GetDeclarativeSecurity(0x20000001);
}
public static IList<CustomAttributeData> __GetDeclarativeSecurity(Type type)
{
if ((type.Attributes & TypeAttributes.HasSecurity) != 0)
{
return type.Module.GetDeclarativeSecurity(type.MetadataToken);
}
else
{
return EmptyList;
}
}
public static IList<CustomAttributeData> __GetDeclarativeSecurity(MethodBase method)
{
if ((method.Attributes & MethodAttributes.HasSecurity) != 0)
{
return method.Module.GetDeclarativeSecurity(method.MetadataToken);
}
else
{
return EmptyList;
}
}
private static bool IsInheritableAttribute(Type attribute)
{
Type attributeUsageAttribute = attribute.Module.universe.System_AttributeUsageAttribute;
IList<CustomAttributeData> attr = attribute.GetCustomAttributesData(attributeUsageAttribute);
if (attr.Count != 0)
{
foreach (CustomAttributeNamedArgument named in attr[0].NamedArguments)
{
if (named.MemberInfo.Name == "Inherited")
{
return (bool)named.TypedValue.Value;
}
}
}
return true;
}
}
}
/*
Copyright (C) 2009 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;
using System.Text;
namespace IKVM.Reflection
{
public struct CustomAttributeNamedArgument
{
private readonly MemberInfo member;
private readonly CustomAttributeTypedArgument value;
internal CustomAttributeNamedArgument(MemberInfo member, CustomAttributeTypedArgument value)
{
this.member = member;
this.value = value;
}
public override bool Equals(object obj)
{
return this == obj as CustomAttributeNamedArgument?;
}
public override int GetHashCode()
{
return member.GetHashCode() ^ 53 * value.GetHashCode();
}
public MemberInfo MemberInfo
{
get { return member; }
}
public CustomAttributeTypedArgument TypedValue
{
get { return value; }
}
public static bool operator ==(CustomAttributeNamedArgument arg1, CustomAttributeNamedArgument arg2)
{
return arg1.member.Equals(arg2.member) && arg1.value == arg2.value;
}
public static bool operator !=(CustomAttributeNamedArgument arg1, CustomAttributeNamedArgument arg2)
{
return !(arg1 == arg2);
}
}
}
/*
Copyright (C) 2009 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;
using System.Text;
namespace IKVM.Reflection
{
public struct CustomAttributeTypedArgument
{
private readonly Type type;
private readonly object value;
internal CustomAttributeTypedArgument(Type type, object value)
{
this.type = type;
this.value = value;
}
public override bool Equals(object obj)
{
return this == obj as CustomAttributeTypedArgument?;
}
public override int GetHashCode()
{
return type.GetHashCode() ^ 77 * (value == null ? 0 : value.GetHashCode());
}
public Type ArgumentType
{
get { return type; }
}
public Object Value
{
get { return value; }
}
public static bool operator ==(CustomAttributeTypedArgument arg1, CustomAttributeTypedArgument arg2)
{
return arg1.type.Equals(arg2.type) && (arg1.value == arg2.value || (arg1.value != null && arg1.value.Equals(arg2.value)));
}
public static bool operator !=(CustomAttributeTypedArgument arg1, CustomAttributeTypedArgument arg2)
{
return !(arg1 == arg2);
}
}
}
此差异已折叠。
/*
Copyright (C) 2008 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;
namespace IKVM.Reflection.Emit
{
public sealed class ConstructorBuilder : ConstructorInfo
{
private readonly MethodBuilder methodBuilder;
internal ConstructorBuilder(MethodBuilder mb)
{
this.methodBuilder = mb;
}
public override bool Equals(object obj)
{
ConstructorBuilder other = obj as ConstructorBuilder;
return other != null && other.methodBuilder.Equals(methodBuilder);
}
public override int GetHashCode()
{
return methodBuilder.GetHashCode();
}
public ParameterBuilder DefineParameter(int position, ParameterAttributes attributes, string strParamName)
{
return methodBuilder.DefineParameter(position, attributes, strParamName);
}
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
{
methodBuilder.SetCustomAttribute(customBuilder);
}
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
methodBuilder.SetCustomAttribute(con, binaryAttribute);
}
public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder)
{
methodBuilder.__AddDeclarativeSecurity(customBuilder);
}
public void AddDeclarativeSecurity(System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet)
{
methodBuilder.AddDeclarativeSecurity(securityAction, permissionSet);
}
public void SetImplementationFlags(MethodImplAttributes attributes)
{
methodBuilder.SetImplementationFlags(attributes);
}
public ILGenerator GetILGenerator()
{
return methodBuilder.GetILGenerator();
}
public ILGenerator GetILGenerator(int streamSize)
{
return methodBuilder.GetILGenerator(streamSize);
}
public override CallingConventions CallingConvention
{
get { return methodBuilder.CallingConvention; }
}
public override MethodAttributes Attributes
{
get { return methodBuilder.Attributes; }
}
public override MethodImplAttributes GetMethodImplementationFlags()
{
return methodBuilder.GetMethodImplementationFlags();
}
public Type ReturnType
{
get { return methodBuilder.ReturnType; }
}
internal override int ParameterCount
{
get { return methodBuilder.ParameterCount; }
}
public override Type DeclaringType
{
get { return methodBuilder.DeclaringType; }
}
public override string Name
{
get { return methodBuilder.Name; }
}
public override int MetadataToken
{
get { return methodBuilder.MetadataToken; }
}
public override Module Module
{
get { return methodBuilder.Module; }
}
public Module GetModule()
{
return methodBuilder.GetModule();
}
public MethodToken GetToken()
{
return methodBuilder.GetToken();
}
public override MethodBody GetMethodBody()
{
return methodBuilder.GetMethodBody();
}
public bool InitLocals
{
get { return methodBuilder.InitLocals; }
set { methodBuilder.InitLocals = value; }
}
internal override MethodInfo GetMethodInfo()
{
return methodBuilder;
}
internal override MethodInfo GetMethodOnTypeDefinition()
{
return methodBuilder;
}
internal override MethodSignature MethodSignature
{
get { return methodBuilder.MethodSignature; }
}
internal override int ImportTo(ModuleBuilder module)
{
return module.ImportMember(methodBuilder);
}
}
}
/*
Copyright (C) 2008 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.IO;
using System.Collections.Generic;
using System.Diagnostics;
using IKVM.Reflection.Writer;
namespace IKVM.Reflection.Emit
{
public sealed class CustomAttributeBuilder
{
private readonly ConstructorInfo con;
private readonly byte[] blob;
private readonly object[] constructorArgs;
private readonly PropertyInfo[] namedProperties;
private readonly object[] propertyValues;
private readonly FieldInfo[] namedFields;
private readonly object[] fieldValues;
internal CustomAttributeBuilder(ConstructorInfo con, byte[] blob)
{
this.con = con;
this.blob = blob;
}
public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs)
: this(con, constructorArgs, null, null, null,null)
{
}
public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, FieldInfo[] namedFields, object[] fieldValues)
: this(con, constructorArgs, null, null, namedFields, fieldValues)
{
}
public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues)
: this(con, constructorArgs, namedProperties, propertyValues, null, null)
{
}
public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues, FieldInfo[] namedFields, object[] fieldValues)
{
this.con = con;
this.constructorArgs = constructorArgs;
this.namedProperties = namedProperties;
this.propertyValues = propertyValues;
this.namedFields = namedFields;
this.fieldValues = fieldValues;
}
private sealed class BlobWriter
{
private readonly ModuleBuilder moduleBuilder;
private readonly CustomAttributeBuilder cab;
private readonly ByteBuffer bb;
internal BlobWriter(ModuleBuilder moduleBuilder, CustomAttributeBuilder cab, ByteBuffer bb)
{
this.moduleBuilder = moduleBuilder;
this.cab = cab;
this.bb = bb;
}
internal void WriteCustomAttributeBlob()
{
// prolog
WriteUInt16(1);
ParameterInfo[] pi = cab.con.GetParameters();
for (int i = 0; i < pi.Length; i++)
{
WriteFixedArg(pi[i].ParameterType, cab.constructorArgs[i]);
}
WriteNamedArguments(false);
}
internal void WriteNamedArguments(bool forDeclSecurity)
{
// NumNamed
int named = 0;
if (cab.namedFields != null)
{
named += cab.namedFields.Length;
}
if (cab.namedProperties != null)
{
named += cab.namedProperties.Length;
}
if (forDeclSecurity)
{
WritePackedLen(named);
}
else
{
WriteUInt16((ushort)named);
}
if (cab.namedFields != null)
{
for (int i = 0; i < cab.namedFields.Length; i++)
{
WriteNamedArg(0x53, cab.namedFields[i].FieldType, cab.namedFields[i].Name, cab.fieldValues[i]);
}
}
if (cab.namedProperties != null)
{
for (int i = 0; i < cab.namedProperties.Length; i++)
{
WriteNamedArg(0x54, cab.namedProperties[i].PropertyType, cab.namedProperties[i].Name, cab.propertyValues[i]);
}
}
}
private void WriteNamedArg(byte fieldOrProperty, Type type, string name, object value)
{
WriteByte(fieldOrProperty);
WriteFieldOrPropType(type);
WriteString(name);
WriteFixedArg(type, value);
}
private void WriteByte(byte value)
{
bb.Write(value);
}
private void WriteUInt16(ushort value)
{
bb.Write(value);
}
private void WriteInt32(int value)
{
bb.Write(value);
}
private void WriteFixedArg(Type type, object value)
{
Universe u = moduleBuilder.universe;
if (type == u.System_String)
{
WriteString((string)value);
}
else if (type == u.System_Type)
{
WriteTypeName((Type)value);
}
else if (type == u.System_Object)
{
if (value == null)
{
type = u.System_String;
}
else if (value is Type)
{
// value.GetType() would return a subclass of Type, but we don't want to deal with that
type = u.System_Type;
}
else
{
type = u.Import(value.GetType());
}
WriteFieldOrPropType(type);
WriteFixedArg(type, value);
}
else if (type.IsArray)
{
if (value == null)
{
WriteInt32(-1);
}
else
{
Array array = (Array)value;
Type elemType = type.GetElementType();
WriteInt32(array.Length);
foreach (object val in array)
{
WriteFixedArg(elemType, val);
}
}
}
else if (type.IsEnum)
{
WriteFixedArg(type.GetEnumUnderlyingTypeImpl(), value);
}
else
{
switch (Type.GetTypeCode(type))
{
case TypeCode.Boolean:
WriteByte((bool)value ? (byte)1 : (byte)0);
break;
case TypeCode.Char:
WriteUInt16((char)value);
break;
case TypeCode.SByte:
WriteByte((byte)(sbyte)value);
break;
case TypeCode.Byte:
WriteByte((byte)value);
break;
case TypeCode.Int16:
WriteUInt16((ushort)(short)value);
break;
case TypeCode.UInt16:
WriteUInt16((ushort)value);
break;
case TypeCode.Int32:
WriteInt32((int)value);
break;
case TypeCode.UInt32:
WriteInt32((int)(uint)value);
break;
case TypeCode.Int64:
WriteInt64((long)value);
break;
case TypeCode.UInt64:
WriteInt64((long)(ulong)value);
break;
case TypeCode.Single:
WriteSingle((float)value);
break;
case TypeCode.Double:
WriteDouble((double)value);
break;
default:
throw new ArgumentException();
}
}
}
private void WriteInt64(long value)
{
bb.Write(value);
}
private void WriteSingle(float value)
{
bb.Write(value);
}
private void WriteDouble(double value)
{
bb.Write(value);
}
private void WriteTypeName(Type type)
{
string name = null;
if (type != null)
{
if (type.Assembly == moduleBuilder.Assembly)
{
name = type.FullName;
}
else
{
name = type.AssemblyQualifiedName;
}
}
WriteString(name);
}
private void WriteString(string val)
{
bb.Write(val);
}
private void WritePackedLen(int len)
{
bb.WriteCompressedInt(len);
}
private void WriteFieldOrPropType(Type type)
{
Universe u = type.Module.universe;
if (type == u.System_Type)
{
WriteByte(0x50);
}
else if (type == u.System_Object)
{
WriteByte(0x51);
}
else if (type.IsArray)
{
WriteByte(0x1D);
WriteFieldOrPropType(type.GetElementType());
}
else if (type.IsEnum)
{
WriteByte(0x55);
WriteTypeName(type);
}
else
{
switch (Type.GetTypeCode(type))
{
case TypeCode.Boolean:
WriteByte(0x02);
break;
case TypeCode.Char:
WriteByte(0x03);
break;
case TypeCode.SByte:
WriteByte(0x04);
break;
case TypeCode.Byte:
WriteByte(0x05);
break;
case TypeCode.Int16:
WriteByte(0x06);
break;
case TypeCode.UInt16:
WriteByte(0x07);
break;
case TypeCode.Int32:
WriteByte(0x08);
break;
case TypeCode.UInt32:
WriteByte(0x09);
break;
case TypeCode.Int64:
WriteByte(0x0A);
break;
case TypeCode.UInt64:
WriteByte(0x0B);
break;
case TypeCode.Single:
WriteByte(0x0C);
break;
case TypeCode.Double:
WriteByte(0x0D);
break;
case TypeCode.String:
WriteByte(0x0E);
break;
default:
throw new ArgumentException();
}
}
}
}
internal bool IsPseudoCustomAttribute
{
get { return con.DeclaringType.IsPseudoCustomAttribute; }
}
internal ConstructorInfo Constructor
{
get { return con; }
}
internal int WriteBlob(ModuleBuilder moduleBuilder)
{
ByteBuffer bb = new ByteBuffer(100);
if (blob != null)
{
bb.Write(blob);
}
else
{
BlobWriter bw = new BlobWriter(moduleBuilder, this, bb);
bw.WriteCustomAttributeBlob();
}
return moduleBuilder.Blobs.Add(bb);
}
internal object GetConstructorArgument(int pos)
{
return constructorArgs[pos];
}
internal int ConstructorArgumentCount
{
get { return constructorArgs == null ? 0 : constructorArgs.Length; }
}
internal T? GetFieldValue<T>(string name) where T : struct
{
object val = GetFieldValue(name);
if (val is T)
{
return (T)val;
}
else if (val != null)
{
if (typeof(T).IsEnum)
{
Debug.Assert(Enum.GetUnderlyingType(typeof(T)) == val.GetType());
return (T)Enum.ToObject(typeof(T), val);
}
else
{
Debug.Assert(Enum.GetUnderlyingType(val.GetType()) == typeof(T));
return (T)Convert.ChangeType(val, typeof(T));
}
}
else
{
return null;
}
}
internal object GetFieldValue(string name)
{
if (namedFields != null)
{
for (int i = 0; i < namedFields.Length; i++)
{
if (namedFields[i].Name == name)
{
return fieldValues[i];
}
}
}
return null;
}
internal void WriteNamedArgumentsForDeclSecurity(ModuleBuilder moduleBuilder, ByteBuffer bb)
{
BlobWriter bw = new BlobWriter(moduleBuilder, this, bb);
bw.WriteNamedArguments(true);
}
internal CustomAttributeData ToData(Assembly asm)
{
if (blob != null)
{
return new CustomAttributeData(asm, con, new IKVM.Reflection.Reader.ByteReader(blob, 0, blob.Length));
}
else
{
List<CustomAttributeNamedArgument> namedArgs = new List<CustomAttributeNamedArgument>();
if (namedProperties != null)
{
for (int i = 0; i < namedProperties.Length; i++)
{
namedArgs.Add(new CustomAttributeNamedArgument(namedProperties[i], new CustomAttributeTypedArgument(namedProperties[i].PropertyType, propertyValues[i])));
}
}
if (namedFields != null)
{
for (int i = 0; i < namedFields.Length; i++)
{
namedArgs.Add(new CustomAttributeNamedArgument(namedFields[i], new CustomAttributeTypedArgument(namedFields[i].FieldType, fieldValues[i])));
}
}
return new CustomAttributeData(con, constructorArgs, namedArgs);
}
}
internal bool HasBlob
{
get { return blob != null; }
}
internal CustomAttributeBuilder DecodeBlob(Assembly asm)
{
if (blob == null)
{
return this;
}
else
{
return ToData(asm).__ToBuilder();
}
}
}
}
/*
Copyright (C) 2010 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;
using System.Text;
namespace IKVM.Reflection.Emit
{
public sealed class EnumBuilder : Type
{
private readonly TypeBuilder typeBuilder;
private readonly FieldBuilder fieldBuilder;
internal EnumBuilder(TypeBuilder typeBuilder, FieldBuilder fieldBuilder)
{
this.typeBuilder = typeBuilder;
this.fieldBuilder = fieldBuilder;
}
public override Type UnderlyingSystemType
{
get { return typeBuilder.UnderlyingSystemType; }
}
public override Type BaseType
{
get { return typeBuilder.BaseType; }
}
public override TypeAttributes Attributes
{
get { return typeBuilder.Attributes; }
}
public override Module Module
{
get { return typeBuilder.Module; }
}
public FieldBuilder DefineLiteral(string literalName, object literalValue)
{
FieldBuilder fb = typeBuilder.DefineField(literalName, typeBuilder, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal);
fb.SetConstant(literalValue);
return fb;
}
public Type CreateType()
{
return typeBuilder.CreateType();
}
public TypeToken TypeToken
{
get { return typeBuilder.TypeToken; }
}
public FieldBuilder UnderlyingField
{
get { return fieldBuilder; }
}
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
typeBuilder.SetCustomAttribute(con, binaryAttribute);
}
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
{
typeBuilder.SetCustomAttribute(customBuilder);
}
public override Type GetEnumUnderlyingType()
{
return fieldBuilder.FieldType;
}
}
}
/*
Copyright (C) 2008 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
*/
namespace IKVM.Reflection.Emit
{
public enum AssemblyBuilderAccess
{
Save = 2,
ReflectionOnly = 6,
}
public enum OpCodeType
{
Annotation = 0,
Macro = 1,
Nternal = 2,
Objmodel = 3,
Prefix = 4,
Primitive = 5,
}
public enum OperandType
{
InlineBrTarget = 0,
InlineField = 1,
InlineI = 2,
InlineI8 = 3,
InlineMethod = 4,
InlineNone = 5,
InlinePhi = 6,
InlineR = 7,
InlineSig = 9,
InlineString = 10,
InlineSwitch = 11,
InlineTok = 12,
InlineType = 13,
InlineVar = 14,
ShortInlineBrTarget = 15,
ShortInlineI = 16,
ShortInlineR = 17,
ShortInlineVar = 18,
}
public enum FlowControl
{
Branch = 0,
Break = 1,
Call = 2,
Cond_Branch = 3,
Meta = 4,
Next = 5,
Return = 7,
Throw = 8,
}
public enum PackingSize
{
Unspecified = 0,
Size1 = 1,
Size2 = 2,
Size4 = 4,
Size8 = 8,
Size16 = 16,
Size32 = 32,
Size64 = 64,
Size128 = 128,
}
public enum PEFileKinds
{
Dll = 1,
ConsoleApplication = 2,
WindowApplication = 3,
}
public enum StackBehaviour
{
Pop0 = 0,
Pop1 = 1,
Pop1_pop1 = 2,
Popi = 3,
Popi_pop1 = 4,
Popi_popi = 5,
Popi_popi8 = 6,
Popi_popi_popi = 7,
Popi_popr4 = 8,
Popi_popr8 = 9,
Popref = 10,
Popref_pop1 = 11,
Popref_popi = 12,
Popref_popi_popi = 13,
Popref_popi_popi8 = 14,
Popref_popi_popr4 = 15,
Popref_popi_popr8 = 16,
Popref_popi_popref = 17,
Push0 = 18,
Push1 = 19,
Push1_push1 = 20,
Pushi = 21,
Pushi8 = 22,
Pushr4 = 23,
Pushr8 = 24,
Pushref = 25,
Varpop = 26,
Varpush = 27,
Popref_popi_pop1 = 28,
}
}
/*
Copyright (C) 2009 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;
using System.Runtime.CompilerServices;
using IKVM.Reflection.Metadata;
using IKVM.Reflection.Writer;
namespace IKVM.Reflection.Emit
{
public sealed class EventBuilder : EventInfo
{
private readonly TypeBuilder typeBuilder;
private readonly string name;
private EventAttributes attributes;
private readonly int eventtype;
private MethodBuilder addOnMethod;
private MethodBuilder removeOnMethod;
private MethodBuilder fireMethod;
private List<MethodBuilder> otherMethods;
private int lazyPseudoToken;
internal EventBuilder(TypeBuilder typeBuilder, string name, EventAttributes attributes, Type eventtype)
{
this.typeBuilder = typeBuilder;
this.name = name;
this.attributes = attributes;
this.eventtype = typeBuilder.ModuleBuilder.GetTypeTokenForMemberRef(eventtype);
}
public void SetAddOnMethod(MethodBuilder mdBuilder)
{
addOnMethod = mdBuilder;
}
public void SetRemoveOnMethod(MethodBuilder mdBuilder)
{
removeOnMethod = mdBuilder;
}
public void SetRaiseMethod(MethodBuilder mdBuilder)
{
fireMethod = mdBuilder;
}
public void AddOtherMethod(MethodBuilder mdBuilder)
{
if (otherMethods == null)
{
otherMethods = new List<MethodBuilder>();
}
otherMethods.Add(mdBuilder);
}
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute));
}
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
{
Universe u = typeBuilder.ModuleBuilder.universe;
if (customBuilder.Constructor.DeclaringType == u.System_Runtime_CompilerServices_SpecialNameAttribute)
{
attributes |= EventAttributes.SpecialName;
}
else
{
if (lazyPseudoToken == 0)
{
lazyPseudoToken = typeBuilder.ModuleBuilder.AllocPseudoToken();
}
typeBuilder.ModuleBuilder.SetCustomAttribute(lazyPseudoToken, customBuilder);
}
}
public override EventAttributes Attributes
{
get { return attributes; }
}
public override MethodInfo GetAddMethod(bool nonPublic)
{
return nonPublic || (addOnMethod != null && addOnMethod.IsPublic) ? addOnMethod : null;
}
public override MethodInfo GetRemoveMethod(bool nonPublic)
{
return nonPublic || (removeOnMethod != null && removeOnMethod.IsPublic) ? removeOnMethod : null;
}
public override MethodInfo GetRaiseMethod(bool nonPublic)
{
return nonPublic || (fireMethod != null && fireMethod.IsPublic) ? fireMethod : null;
}
public override MethodInfo[] GetOtherMethods(bool nonPublic)
{
List<MethodInfo> list = new List<MethodInfo>();
if (otherMethods != null)
{
foreach (MethodInfo method in otherMethods)
{
if (nonPublic || method.IsPublic)
{
list.Add(method);
}
}
}
return list.ToArray();
}
public override Type DeclaringType
{
get { return typeBuilder; }
}
public override string Name
{
get { return name; }
}
public override Module Module
{
get { return typeBuilder.ModuleBuilder; }
}
public EventToken GetEventToken()
{
if (lazyPseudoToken == 0)
{
lazyPseudoToken = typeBuilder.ModuleBuilder.AllocPseudoToken();
}
return new EventToken(lazyPseudoToken);
}
public override Type EventHandlerType
{
get { return typeBuilder.ModuleBuilder.ResolveType(eventtype); }
}
internal void Bake()
{
EventTable.Record rec = new EventTable.Record();
rec.EventFlags = (short)attributes;
rec.Name = typeBuilder.ModuleBuilder.Strings.Add(name);
rec.EventType = eventtype;
int token = 0x14000000 | typeBuilder.ModuleBuilder.Event.AddRecord(rec);
if (lazyPseudoToken != 0)
{
typeBuilder.ModuleBuilder.RegisterTokenFixup(lazyPseudoToken, token);
}
if (addOnMethod != null)
{
AddMethodSemantics(MethodSemanticsTable.AddOn, addOnMethod.MetadataToken, token);
}
if (removeOnMethod != null)
{
AddMethodSemantics(MethodSemanticsTable.RemoveOn, removeOnMethod.MetadataToken, token);
}
if (fireMethod != null)
{
AddMethodSemantics(MethodSemanticsTable.Fire, fireMethod.MetadataToken, token);
}
if (otherMethods != null)
{
foreach (MethodBuilder method in otherMethods)
{
AddMethodSemantics(MethodSemanticsTable.Other, method.MetadataToken, token);
}
}
}
private void AddMethodSemantics(short semantics, int methodToken, int propertyToken)
{
MethodSemanticsTable.Record rec = new MethodSemanticsTable.Record();
rec.Semantics = semantics;
rec.Method = methodToken;
rec.Association = propertyToken;
typeBuilder.ModuleBuilder.MethodSemantics.AddRecord(rec);
}
internal override bool IsPublic
{
get
{
if ((addOnMethod != null && addOnMethod.IsPublic) || (removeOnMethod != null && removeOnMethod.IsPublic) || (fireMethod != null && fireMethod.IsPublic))
{
return true;
}
if (otherMethods != null)
{
foreach (MethodBuilder method in otherMethods)
{
if (method.IsPublic)
{
return true;
}
}
}
return false;
}
}
internal override bool IsStatic
{
get
{
if ((addOnMethod != null && addOnMethod.IsStatic) || (removeOnMethod != null && removeOnMethod.IsStatic) || (fireMethod != null && fireMethod.IsStatic))
{
return true;
}
if (otherMethods != null)
{
foreach (MethodBuilder method in otherMethods)
{
if (method.IsStatic)
{
return true;
}
}
}
return false;
}
}
}
}
/*
Copyright (C) 2008 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.Runtime.CompilerServices;
using IKVM.Reflection.Metadata;
using IKVM.Reflection.Writer;
namespace IKVM.Reflection.Emit
{
public sealed class FieldBuilder : FieldInfo
{
private readonly TypeBuilder typeBuilder;
private readonly string name;
private readonly int pseudoToken;
private FieldAttributes attribs;
private readonly int nameIndex;
private readonly int signature;
private readonly FieldSignature fieldSig;
internal FieldBuilder(TypeBuilder type, string name, Type fieldType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, FieldAttributes attribs)
{
this.typeBuilder = type;
this.name = name;
this.pseudoToken = type.ModuleBuilder.AllocPseudoToken();
this.nameIndex = type.ModuleBuilder.Strings.Add(name);
this.fieldSig = FieldSignature.Create(fieldType, optionalCustomModifiers, requiredCustomModifiers);
ByteBuffer sig = new ByteBuffer(5);
fieldSig.WriteSig(this.typeBuilder.ModuleBuilder, sig);
this.signature = this.typeBuilder.ModuleBuilder.Blobs.Add(sig);
this.attribs = attribs;
this.typeBuilder.ModuleBuilder.Field.AddVirtualRecord();
}
public void SetConstant(object defaultValue)
{
attribs |= FieldAttributes.HasDefault;
typeBuilder.ModuleBuilder.AddConstant(pseudoToken, defaultValue);
}
public override object GetRawConstantValue()
{
return typeBuilder.Module.Constant.GetRawConstantValue(typeBuilder.Module, this.MetadataToken);
}
public void __SetDataAndRVA(byte[] data)
{
attribs |= FieldAttributes.HasFieldRVA;
FieldRVATable.Record rec = new FieldRVATable.Record();
rec.RVA = typeBuilder.ModuleBuilder.initializedData.Position;
rec.Field = pseudoToken;
typeBuilder.ModuleBuilder.FieldRVA.AddRecord(rec);
typeBuilder.ModuleBuilder.initializedData.Write(data);
}
public override void __GetDataFromRVA(byte[] data, int offset, int length)
{
throw new NotImplementedException();
}
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute));
}
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
{
Universe u = this.Module.universe;
if (customBuilder.Constructor.DeclaringType == u.System_Runtime_InteropServices_FieldOffsetAttribute)
{
customBuilder = customBuilder.DecodeBlob(this.Module.Assembly);
SetOffset((int)customBuilder.GetConstructorArgument(0));
}
else if (customBuilder.Constructor.DeclaringType == u.System_Runtime_InteropServices_MarshalAsAttribute)
{
MarshalSpec.SetMarshalAsAttribute(typeBuilder.ModuleBuilder, pseudoToken, customBuilder);
attribs |= FieldAttributes.HasFieldMarshal;
}
else if (customBuilder.Constructor.DeclaringType == u.System_NonSerializedAttribute)
{
attribs |= FieldAttributes.NotSerialized;
}
else if (customBuilder.Constructor.DeclaringType == u.System_Runtime_CompilerServices_SpecialNameAttribute)
{
attribs |= FieldAttributes.SpecialName;
}
else
{
typeBuilder.ModuleBuilder.SetCustomAttribute(pseudoToken, customBuilder);
}
}
public void SetOffset(int iOffset)
{
FieldLayoutTable.Record rec = new FieldLayoutTable.Record();
rec.Offset = iOffset;
rec.Field = pseudoToken;
typeBuilder.ModuleBuilder.FieldLayout.AddRecord(rec);
}
public override FieldAttributes Attributes
{
get { return attribs; }
}
public override Type DeclaringType
{
get { return typeBuilder.IsModulePseudoType ? null : typeBuilder; }
}
public override string Name
{
get { return name; }
}
public override int MetadataToken
{
get { return pseudoToken; }
}
public override Module Module
{
get { return typeBuilder.Module; }
}
public FieldToken GetToken()
{
return new FieldToken(pseudoToken);
}
internal void WriteFieldRecords(MetadataWriter mw)
{
mw.Write((short)attribs);
mw.WriteStringIndex(nameIndex);
mw.WriteBlobIndex(signature);
}
internal void FixupToken(int token)
{
typeBuilder.ModuleBuilder.RegisterTokenFixup(this.pseudoToken, token);
}
internal override FieldSignature FieldSignature
{
get { return fieldSig; }
}
internal override int ImportTo(ModuleBuilder other)
{
if (typeBuilder.IsGenericTypeDefinition)
{
return other.ImportMember(TypeBuilder.GetField(typeBuilder, this));
}
else if (other == typeBuilder.ModuleBuilder)
{
return pseudoToken;
}
else
{
return other.ImportMethodOrField(typeBuilder, name, fieldSig);
}
}
}
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
Copyright (C) 2008, 2010 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.Diagnostics;
namespace IKVM.Reflection.Emit
{
public struct OpCode
{
private const int ValueCount = 1024;
private const int OperandTypeCount = 19;
private const int FlowControlCount = 9;
private const int StackDiffCount = 5;
private const int OpCodeTypeCount = 6;
private const int StackBehaviourPopCount = 20;
private const int StackBehaviourPushCount = 9;
private static readonly StackBehaviour[] pop = {
StackBehaviour.Pop0,
StackBehaviour.Pop1,
StackBehaviour.Pop1_pop1,
StackBehaviour.Popi,
StackBehaviour.Popi_pop1,
StackBehaviour.Popi_popi,
StackBehaviour.Popi_popi8,
StackBehaviour.Popi_popi_popi,
StackBehaviour.Popi_popr4,
StackBehaviour.Popi_popr8,
StackBehaviour.Popref,
StackBehaviour.Popref_pop1,
StackBehaviour.Popref_popi,
StackBehaviour.Popref_popi_popi,
StackBehaviour.Popref_popi_popi8,
StackBehaviour.Popref_popi_popr4,
StackBehaviour.Popref_popi_popr8,
StackBehaviour.Popref_popi_popref,
StackBehaviour.Varpop,
StackBehaviour.Popref_popi_pop1
};
private static readonly StackBehaviour[] push = {
StackBehaviour.Push0,
StackBehaviour.Push1,
StackBehaviour.Push1_push1,
StackBehaviour.Pushi,
StackBehaviour.Pushi8,
StackBehaviour.Pushr4,
StackBehaviour.Pushr8,
StackBehaviour.Pushref,
StackBehaviour.Varpush
};
private readonly int value;
internal OpCode(int value)
{
this.value = value;
}
public override bool Equals(object obj)
{
return this == obj as OpCode?;
}
public override int GetHashCode()
{
return value;
}
public bool Equals(OpCode other)
{
return this == other;
}
public static bool operator ==(OpCode a, OpCode b)
{
return a.value == b.value;
}
public static bool operator !=(OpCode a, OpCode b)
{
return !(a == b);
}
public short Value
{
get { return (short)(value >> 22); }
}
public int Size
{
get { return value < 0 ? 2 : 1; }
}
#if !GENERATOR
public string Name
{
get { return OpCodes.GetName(this.Value); }
}
#endif
public OperandType OperandType
{
get { return (OperandType)((value & 0x3FFFFF) % OperandTypeCount); }
}
public FlowControl FlowControl
{
get { return (FlowControl)(((value & 0x3FFFFF) / OperandTypeCount) % FlowControlCount); }
}
internal int StackDiff
{
get { return ((((value & 0x3FFFFF) / (OperandTypeCount * FlowControlCount)) % StackDiffCount) - 3); }
}
public OpCodeType OpCodeType
{
get { return (OpCodeType)(((value & 0x3FFFFF) / (OperandTypeCount * FlowControlCount * StackDiffCount)) % OpCodeTypeCount); }
}
public StackBehaviour StackBehaviourPop
{
get { return pop[(((value & 0x3FFFFF) / (OperandTypeCount * FlowControlCount * StackDiffCount * OpCodeTypeCount)) % StackBehaviourPopCount)]; }
}
public StackBehaviour StackBehaviourPush
{
get { return push[(((value & 0x3FFFFF) / (OperandTypeCount * FlowControlCount * StackDiffCount * OpCodeTypeCount * StackBehaviourPopCount)) % StackBehaviourPushCount)]; }
}
#if GENERATOR
static void Main(string[] args)
{
Debug.Assert(pop.Length == StackBehaviourPopCount);
Debug.Assert(push.Length == StackBehaviourPushCount);
CheckEnumRange(typeof(FlowControl), FlowControlCount);
CheckEnumRange(typeof(OpCodeType), OpCodeTypeCount);
CheckEnumRange(typeof(OperandType), OperandTypeCount);
foreach (var field in typeof(System.Reflection.Emit.OpCodes).GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static))
{
System.Reflection.Emit.OpCode opc1 = (System.Reflection.Emit.OpCode)field.GetValue(null);
IKVM.Reflection.Emit.OpCode opc2 = new IKVM.Reflection.Emit.OpCode(Pack(opc1));
Debug.Assert(opc1.Value == opc2.Value);
Debug.Assert(opc1.Size == opc2.Size);
Debug.Assert((int)opc1.FlowControl == (int)opc2.FlowControl);
Debug.Assert((int)opc1.OpCodeType == (int)opc2.OpCodeType);
Debug.Assert((int)opc1.OperandType == (int)opc2.OperandType);
Debug.Assert((int)opc1.StackBehaviourPop == (int)opc2.StackBehaviourPop);
Debug.Assert((int)opc1.StackBehaviourPush == (int)opc2.StackBehaviourPush);
Console.WriteLine("\t\tpublic static readonly OpCode {0} = new OpCode({1});", field.Name, Pack(opc1));
}
Console.WriteLine();
Console.WriteLine("\t\tinternal static string GetName(int value)");
Console.WriteLine("\t\t{");
Console.WriteLine("\t\t\tswitch (value)");
Console.WriteLine("\t\t\t{");
foreach (var field in typeof(System.Reflection.Emit.OpCodes).GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static))
{
System.Reflection.Emit.OpCode opc1 = (System.Reflection.Emit.OpCode)field.GetValue(null);
Console.WriteLine("\t\t\t\tcase {0}:", opc1.Value);
Console.WriteLine("\t\t\t\t\treturn \"{0}\";", opc1.Name);
}
Console.WriteLine("\t\t\t}");
Console.WriteLine("\t\t\tthrow new ArgumentOutOfRangeException();");
Console.WriteLine("\t\t}");
Console.WriteLine();
Console.WriteLine("\t\tpublic static bool TakesSingleByteArgument(OpCode inst)");
Console.WriteLine("\t\t{");
Console.WriteLine("\t\t\tswitch (inst.Value)");
Console.WriteLine("\t\t\t{");
foreach (var field in typeof(System.Reflection.Emit.OpCodes).GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static))
{
System.Reflection.Emit.OpCode opc1 = (System.Reflection.Emit.OpCode)field.GetValue(null);
if (System.Reflection.Emit.OpCodes.TakesSingleByteArgument(opc1))
{
Console.WriteLine("\t\t\t\tcase {0}:", opc1.Value);
}
}
Console.WriteLine("\t\t\t\t\treturn true;");
Console.WriteLine("\t\t\t\tdefault:");
Console.WriteLine("\t\t\t\t\treturn false;");
Console.WriteLine("\t\t\t}");
Console.WriteLine("\t\t}");
}
private static void CheckEnumRange(System.Type type, int count)
{
foreach (var field in type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static))
{
int value = (int)field.GetValue(null);
Debug.Assert(value >= 0 && value < count);
}
}
static int Pack(System.Reflection.Emit.OpCode opcode)
{
int value = 0;
value *= StackBehaviourPushCount;
value += Map(push, opcode.StackBehaviourPush);
value *= StackBehaviourPopCount;
value += Map(pop, opcode.StackBehaviourPop);
value *= OpCodeTypeCount;
value += (int)opcode.OpCodeType;
value *= StackDiffCount;
value += 3 + GetStackDiff(opcode.StackBehaviourPush) + GetStackDiff(opcode.StackBehaviourPop);
value *= FlowControlCount;
value += (int)opcode.FlowControl;
value *= OperandTypeCount;
value += (int)opcode.OperandType;
return (opcode.Value << 22) | value;
}
private static int Map(StackBehaviour[] array, System.Reflection.Emit.StackBehaviour stackBehaviour)
{
for (int i = 0; i < array.Length; i++)
{
if ((int)array[i] == (int)stackBehaviour)
{
return i;
}
}
throw new InvalidOperationException();
}
static int GetStackDiff(System.Reflection.Emit.StackBehaviour sb)
{
switch (sb)
{
case System.Reflection.Emit.StackBehaviour.Pop0:
case System.Reflection.Emit.StackBehaviour.Push0:
case System.Reflection.Emit.StackBehaviour.Varpop:
case System.Reflection.Emit.StackBehaviour.Varpush:
return 0;
case System.Reflection.Emit.StackBehaviour.Pop1:
case System.Reflection.Emit.StackBehaviour.Popi:
case System.Reflection.Emit.StackBehaviour.Popref:
return -1;
case System.Reflection.Emit.StackBehaviour.Pop1_pop1:
case System.Reflection.Emit.StackBehaviour.Popi_pop1:
case System.Reflection.Emit.StackBehaviour.Popi_popi:
case System.Reflection.Emit.StackBehaviour.Popi_popi8:
case System.Reflection.Emit.StackBehaviour.Popi_popr4:
case System.Reflection.Emit.StackBehaviour.Popi_popr8:
case System.Reflection.Emit.StackBehaviour.Popref_pop1:
case System.Reflection.Emit.StackBehaviour.Popref_popi:
return -2;
case System.Reflection.Emit.StackBehaviour.Popi_popi_popi:
case System.Reflection.Emit.StackBehaviour.Popref_popi_pop1:
case System.Reflection.Emit.StackBehaviour.Popref_popi_popi:
case System.Reflection.Emit.StackBehaviour.Popref_popi_popi8:
case System.Reflection.Emit.StackBehaviour.Popref_popi_popr4:
case System.Reflection.Emit.StackBehaviour.Popref_popi_popr8:
case System.Reflection.Emit.StackBehaviour.Popref_popi_popref:
return -3;
case System.Reflection.Emit.StackBehaviour.Push1:
case System.Reflection.Emit.StackBehaviour.Pushi:
case System.Reflection.Emit.StackBehaviour.Pushi8:
case System.Reflection.Emit.StackBehaviour.Pushr4:
case System.Reflection.Emit.StackBehaviour.Pushr8:
case System.Reflection.Emit.StackBehaviour.Pushref:
return 1;
case System.Reflection.Emit.StackBehaviour.Push1_push1:
return 2;
}
throw new InvalidOperationException();
}
#endif // GENERATOR
}
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
Copyright (C) 2008 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.Reflection;
using System.Runtime.CompilerServices;
[assembly: AssemblyTitle("IKVM.NET Reflection")]
[assembly: AssemblyDescription("Managed (partial) Reflection implementation for use by ikvmc")]
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册