Skip to content

Instantly share code, notes, and snippets.

@jcansdale
Created October 17, 2018 18:13
Show Gist options
  • Save jcansdale/2d97240b53b23e14ec5324c4fe0916bb to your computer and use it in GitHub Desktop.
Save jcansdale/2d97240b53b23e14ec5324c4fe0916bb to your computer and use it in GitHub Desktop.
proj2src Mono.Cecil.csproj Mono.Cecil.cs
#region ProjectInfo.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
//
// Licensed under the MIT/X11 license.
//
using System.Reflection;
using System.Runtime.InteropServices;
/*[assembly: AssemblyProduct (Consts.AssemblyName)]*/
/*[assembly: AssemblyCopyright ("Copyright © 2008 - 2018 Jb Evain")]*/
/*[assembly: ComVisible (false)]*/
/*[assembly: AssemblyVersion ("0.10.1.0")]*/
/*[assembly: AssemblyFileVersion ("0.10.1.0")]*/
/*[assembly: AssemblyInformationalVersion ("0.10.1.0")]*/
}
#endregion
#region Mono\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono {
static class Disposable {
public static Disposable<T> Owned<T> (T value) where T : class, IDisposable
{
return new Disposable<T> (value, owned: true);
}
public static Disposable<T> NotOwned<T> (T value) where T : class, IDisposable
{
return new Disposable<T> (value, owned: false);
}
}
struct Disposable<T> : IDisposable where T : class, IDisposable {
internal readonly T value;
readonly bool owned;
public Disposable (T value, bool owned)
{
this.value = value;
this.owned = owned;
}
public void Dispose ()
{
if (value != null && owned)
value.Dispose ();
}
}
}
}
#endregion
#region Mono\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Collections.Generic;
namespace Mono {
static class Empty<T> {
public static readonly T [] Array = new T [0];
}
class ArgumentNullOrEmptyException : ArgumentException {
public ArgumentNullOrEmptyException (string paramName)
: base ("Argument null or empty", paramName)
{
}
}
}
namespace Mono.Cecil {
static partial class Mixin {
public static bool IsNullOrEmpty<T> (this T [] self)
{
return self == null || self.Length == 0;
}
public static bool IsNullOrEmpty<T> (this Collection<T> self)
{
return self == null || self.size == 0;
}
public static T [] Resize<T> (this T [] self, int length)
{
Array.Resize (ref self, length);
return self;
}
public static T [] Add<T> (this T [] self, T item)
{
if (self == null) {
self = new [] { item };
return self;
}
self = self.Resize (self.Length + 1);
self [self.Length - 1] = item;
return self;
}
}
}
}
#endregion
#region Mono\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Reflection;
#if NET_CORE
using System.Collections.Generic;
#endif
namespace Mono {
#if NET_CORE
enum TypeCode {
Empty = 0,
Object = 1,
DBNull = 2,
Boolean = 3,
Char = 4,
SByte = 5,
Byte = 6,
Int16 = 7,
UInt16 = 8,
Int32 = 9,
UInt32 = 10,
Int64 = 11,
UInt64 = 12,
Single = 13,
Double = 14,
Decimal = 15,
DateTime = 16,
String = 18
}
#endif
static class TypeExtensions {
#if NET_CORE
private static readonly Dictionary<Type, TypeCode> TypeCodeMap = new Dictionary<Type, TypeCode>
{
{ typeof (bool), TypeCode.Boolean },
{ typeof (char), TypeCode.Char },
{ typeof (sbyte), TypeCode.SByte },
{ typeof (byte), TypeCode.Byte },
{ typeof (short), TypeCode.Int16 },
{ typeof (ushort), TypeCode.UInt16 },
{ typeof (int), TypeCode.Int32 },
{ typeof (uint), TypeCode.UInt32 },
{ typeof (long), TypeCode.Int64 },
{ typeof (ulong), TypeCode.UInt64 },
{ typeof (float), TypeCode.Single },
{ typeof (double), TypeCode.Double },
{ typeof (decimal), TypeCode.Decimal },
{ typeof (DateTime), TypeCode.DateTime },
{ typeof (string), TypeCode.String },
};
#endif
public static TypeCode GetTypeCode (this Type type)
{
#if NET_CORE
if (type == null)
return TypeCode.Empty;
TypeCode code;
if (!TypeCodeMap.TryGetValue (type, out code))
return TypeCode.Object;
return code;
#else
return Type.GetTypeCode (type);
#endif
}
public static Assembly Assembly (this Type type)
{
#if NET_CORE
return type.GetTypeInfo ().Assembly;
#else
return type.Assembly;
#endif
}
public static MethodBase DeclaringMethod (this Type type)
{
#if NET_CORE
return type.GetTypeInfo ().DeclaringMethod;
#else
return type.DeclaringMethod;
#endif
}
public static Type [] GetGenericArguments (this Type type)
{
#if NET_CORE
var info = type.GetTypeInfo ();
return info.IsGenericTypeDefinition ? info.GenericTypeParameters : info.GenericTypeArguments;
#else
return type.GetGenericArguments ();
#endif
}
public static bool IsGenericType (this Type type)
{
#if NET_CORE
return type.GetTypeInfo ().IsGenericType;
#else
return type.IsGenericType;
#endif
}
public static bool IsGenericTypeDefinition (this Type type)
{
#if NET_CORE
return type.GetTypeInfo ().IsGenericTypeDefinition;
#else
return type.IsGenericTypeDefinition;
#endif
}
public static bool IsValueType (this Type type)
{
#if NET_CORE
return type.GetTypeInfo ().IsValueType;
#else
return type.IsValueType;
#endif
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Text;
using Mono.Collections.Generic;
using MD = Mono.Cecil.Metadata;
namespace Mono.Cecil {
internal struct ArrayDimension {
int? lower_bound;
int? upper_bound;
public int? LowerBound {
get { return lower_bound; }
set { lower_bound = value; }
}
public int? UpperBound {
get { return upper_bound; }
set { upper_bound = value; }
}
public bool IsSized {
get { return lower_bound.HasValue || upper_bound.HasValue; }
}
public ArrayDimension (int? lowerBound, int? upperBound)
{
this.lower_bound = lowerBound;
this.upper_bound = upperBound;
}
public override string ToString ()
{
return !IsSized
? string.Empty
: lower_bound + "..." + upper_bound;
}
}
internal sealed class ArrayType : TypeSpecification {
Collection<ArrayDimension> dimensions;
public Collection<ArrayDimension> Dimensions {
get {
if (dimensions != null)
return dimensions;
dimensions = new Collection<ArrayDimension> ();
dimensions.Add (new ArrayDimension ());
return dimensions;
}
}
public int Rank {
get { return dimensions == null ? 1 : dimensions.Count; }
}
public bool IsVector {
get {
if (dimensions == null)
return true;
if (dimensions.Count > 1)
return false;
var dimension = dimensions [0];
return !dimension.IsSized;
}
}
public override bool IsValueType {
get { return false; }
set { throw new InvalidOperationException (); }
}
public override string Name {
get { return base.Name + Suffix; }
}
public override string FullName {
get { return base.FullName + Suffix; }
}
string Suffix {
get {
if (IsVector)
return "[]";
var suffix = new StringBuilder ();
suffix.Append ("[");
for (int i = 0; i < dimensions.Count; i++) {
if (i > 0)
suffix.Append (",");
suffix.Append (dimensions [i].ToString ());
}
suffix.Append ("]");
return suffix.ToString ();
}
}
public override bool IsArray {
get { return true; }
}
public ArrayType (TypeReference type)
: base (type)
{
Mixin.CheckType (type);
this.etype = MD.ElementType.Array;
}
public ArrayType (TypeReference type, int rank)
: this (type)
{
Mixin.CheckType (type);
if (rank == 1)
return;
dimensions = new Collection<ArrayDimension> (rank);
for (int i = 0; i < rank; i++)
dimensions.Add (new ArrayDimension ());
this.etype = MD.ElementType.Array;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.IO;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal sealed class AssemblyDefinition : ICustomAttributeProvider, ISecurityDeclarationProvider, IDisposable {
AssemblyNameDefinition name;
internal ModuleDefinition main_module;
Collection<ModuleDefinition> modules;
Collection<CustomAttribute> custom_attributes;
Collection<SecurityDeclaration> security_declarations;
public AssemblyNameDefinition Name {
get { return name; }
set { name = value; }
}
public string FullName {
get { return name != null ? name.FullName : string.Empty; }
}
public MetadataToken MetadataToken {
get { return new MetadataToken (TokenType.Assembly, 1); }
set { }
}
public Collection<ModuleDefinition> Modules {
get {
if (modules != null)
return modules;
if (main_module.HasImage)
return main_module.Read (ref modules, this, (_, reader) => reader.ReadModules ());
return modules = new Collection<ModuleDefinition> (1) { main_module };
}
}
public ModuleDefinition MainModule {
get { return main_module; }
}
public MethodDefinition EntryPoint {
get { return main_module.EntryPoint; }
set { main_module.EntryPoint = value; }
}
public bool HasCustomAttributes {
get {
if (custom_attributes != null)
return custom_attributes.Count > 0;
return this.GetHasCustomAttributes (main_module);
}
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, main_module)); }
}
public bool HasSecurityDeclarations {
get {
if (security_declarations != null)
return security_declarations.Count > 0;
return this.GetHasSecurityDeclarations (main_module);
}
}
public Collection<SecurityDeclaration> SecurityDeclarations {
get { return security_declarations ?? (this.GetSecurityDeclarations (ref security_declarations, main_module)); }
}
internal AssemblyDefinition ()
{
}
public void Dispose ()
{
if (this.modules == null) {
main_module.Dispose ();
return;
}
var modules = this.Modules;
for (int i = 0; i < modules.Count; i++)
modules [i].Dispose ();
}
#if !READ_ONLY
public static AssemblyDefinition CreateAssembly (AssemblyNameDefinition assemblyName, string moduleName, ModuleKind kind)
{
return CreateAssembly (assemblyName, moduleName, new ModuleParameters { Kind = kind });
}
public static AssemblyDefinition CreateAssembly (AssemblyNameDefinition assemblyName, string moduleName, ModuleParameters parameters)
{
if (assemblyName == null)
throw new ArgumentNullException ("assemblyName");
if (moduleName == null)
throw new ArgumentNullException ("moduleName");
Mixin.CheckParameters (parameters);
if (parameters.Kind == ModuleKind.NetModule)
throw new ArgumentException ("kind");
var assembly = ModuleDefinition.CreateModule (moduleName, parameters).Assembly;
assembly.Name = assemblyName;
return assembly;
}
#endif
public static AssemblyDefinition ReadAssembly (string fileName)
{
return ReadAssembly (ModuleDefinition.ReadModule (fileName));
}
public static AssemblyDefinition ReadAssembly (string fileName, ReaderParameters parameters)
{
return ReadAssembly (ModuleDefinition.ReadModule (fileName, parameters));
}
public static AssemblyDefinition ReadAssembly (Stream stream)
{
return ReadAssembly (ModuleDefinition.ReadModule (stream));
}
public static AssemblyDefinition ReadAssembly (Stream stream, ReaderParameters parameters)
{
return ReadAssembly (ModuleDefinition.ReadModule (stream, parameters));
}
static AssemblyDefinition ReadAssembly (ModuleDefinition module)
{
var assembly = module.Assembly;
if (assembly == null)
throw new ArgumentException ();
return assembly;
}
#if !READ_ONLY
public void Write (string fileName)
{
Write (fileName, new WriterParameters ());
}
public void Write (string fileName, WriterParameters parameters)
{
main_module.Write (fileName, parameters);
}
public void Write ()
{
main_module.Write ();
}
public void Write (WriterParameters parameters)
{
main_module.Write (parameters);
}
public void Write (Stream stream)
{
Write (stream, new WriterParameters ());
}
public void Write (Stream stream, WriterParameters parameters)
{
main_module.Write (stream, parameters);
}
#endif
public override string ToString ()
{
return this.FullName;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
[Flags]
internal enum AssemblyAttributes : uint {
PublicKey = 0x0001,
SideBySideCompatible = 0x0000,
Retargetable = 0x0100,
WindowsRuntime = 0x0200,
DisableJITCompileOptimizer = 0x4000,
EnableJITCompileTracking = 0x8000,
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil {
internal enum AssemblyHashAlgorithm : uint {
None = 0x0000,
Reserved = 0x8003, // MD5
SHA1 = 0x8004
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
/*[assembly: AssemblyTitle (Consts.AssemblyName)]*/
#if !NET_CORE
/*[assembly: Guid ("fd225bb4-fa53-44b2-a6db-85f5e48dcb54")]*/
#endif
/*[assembly: InternalsVisibleTo ("Mono.Cecil.Pdb, PublicKey=" + Consts.PublicKey)]*/
/*[assembly: InternalsVisibleTo ("Mono.Cecil.Mdb, PublicKey=" + Consts.PublicKey)]*/
/*[assembly: InternalsVisibleTo ("Mono.Cecil.Rocks, PublicKey=" + Consts.PublicKey)]*/
/*[assembly: InternalsVisibleTo ("Mono.Cecil.Tests, PublicKey=" + Consts.PublicKey)]*/
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
internal sealed class AssemblyLinkedResource : Resource {
AssemblyNameReference reference;
public AssemblyNameReference Assembly {
get { return reference; }
set { reference = value; }
}
public override ResourceType ResourceType {
get { return ResourceType.AssemblyLinked; }
}
public AssemblyLinkedResource (string name, ManifestResourceAttributes flags)
: base (name, flags)
{
}
public AssemblyLinkedResource (string name, ManifestResourceAttributes flags, AssemblyNameReference reference)
: base (name, flags)
{
this.reference = reference;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
internal sealed class AssemblyNameDefinition : AssemblyNameReference {
public override byte [] Hash {
get { return Empty<byte>.Array; }
}
internal AssemblyNameDefinition ()
{
this.token = new MetadataToken (TokenType.Assembly, 1);
}
public AssemblyNameDefinition (string name, Version version)
: base (name, version)
{
this.token = new MetadataToken (TokenType.Assembly, 1);
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
namespace Mono.Cecil {
internal class AssemblyNameReference : IMetadataScope {
string name;
string culture;
Version version;
uint attributes;
byte [] public_key;
byte [] public_key_token;
AssemblyHashAlgorithm hash_algorithm;
byte [] hash;
internal MetadataToken token;
string full_name;
public string Name {
get { return name; }
set {
name = value;
full_name = null;
}
}
public string Culture {
get { return culture; }
set {
culture = value;
full_name = null;
}
}
public Version Version {
get { return version; }
set {
version = Mixin.CheckVersion (value);
full_name = null;
}
}
public AssemblyAttributes Attributes {
get { return (AssemblyAttributes) attributes; }
set { attributes = (uint) value; }
}
public bool HasPublicKey {
get { return attributes.GetAttributes ((uint) AssemblyAttributes.PublicKey); }
set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.PublicKey, value); }
}
public bool IsSideBySideCompatible {
get { return attributes.GetAttributes ((uint) AssemblyAttributes.SideBySideCompatible); }
set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.SideBySideCompatible, value); }
}
public bool IsRetargetable {
get { return attributes.GetAttributes ((uint) AssemblyAttributes.Retargetable); }
set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.Retargetable, value); }
}
public bool IsWindowsRuntime {
get { return attributes.GetAttributes ((uint) AssemblyAttributes.WindowsRuntime); }
set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.WindowsRuntime, value); }
}
public byte [] PublicKey {
get { return public_key ?? Empty<byte>.Array; }
set {
public_key = value;
HasPublicKey = !public_key.IsNullOrEmpty ();
public_key_token = Empty<byte>.Array;
full_name = null;
}
}
public byte [] PublicKeyToken {
get {
if (public_key_token.IsNullOrEmpty () && !public_key.IsNullOrEmpty ()) {
var hash = HashPublicKey ();
// we need the last 8 bytes in reverse order
var local_public_key_token = new byte [8];
Array.Copy (hash, (hash.Length - 8), local_public_key_token, 0, 8);
Array.Reverse (local_public_key_token, 0, 8);
public_key_token = local_public_key_token; // publish only once finished (required for thread-safety)
}
return public_key_token ?? Empty<byte>.Array;
}
set {
public_key_token = value;
full_name = null;
}
}
byte [] HashPublicKey ()
{
HashAlgorithm algorithm;
switch (hash_algorithm) {
case AssemblyHashAlgorithm.Reserved:
algorithm = MD5.Create ();
break;
default:
// None default to SHA1
algorithm = SHA1.Create ();
break;
}
using (algorithm)
return algorithm.ComputeHash (public_key);
}
public virtual MetadataScopeType MetadataScopeType {
get { return MetadataScopeType.AssemblyNameReference; }
}
public string FullName {
get {
if (full_name != null)
return full_name;
const string sep = ", ";
var builder = new StringBuilder ();
builder.Append (name);
builder.Append (sep);
builder.Append ("Version=");
builder.Append (version.ToString (fieldCount: 4));
builder.Append (sep);
builder.Append ("Culture=");
builder.Append (string.IsNullOrEmpty (culture) ? "neutral" : culture);
builder.Append (sep);
builder.Append ("PublicKeyToken=");
var pk_token = PublicKeyToken;
if (!pk_token.IsNullOrEmpty () && pk_token.Length > 0) {
for (int i = 0 ; i < pk_token.Length ; i++) {
builder.Append (pk_token [i].ToString ("x2"));
}
} else
builder.Append ("null");
if (IsRetargetable) {
builder.Append (sep);
builder.Append ("Retargetable=Yes");
}
return full_name = builder.ToString ();
}
}
public static AssemblyNameReference Parse (string fullName)
{
if (fullName == null)
throw new ArgumentNullException ("fullName");
if (fullName.Length == 0)
throw new ArgumentException ("Name can not be empty");
var name = new AssemblyNameReference ();
var tokens = fullName.Split (',');
for (int i = 0; i < tokens.Length; i++) {
var token = tokens [i].Trim ();
if (i == 0) {
name.Name = token;
continue;
}
var parts = token.Split ('=');
if (parts.Length != 2)
throw new ArgumentException ("Malformed name");
switch (parts [0].ToLowerInvariant ()) {
case "version":
name.Version = new Version (parts [1]);
break;
case "culture":
name.Culture = parts [1] == "neutral" ? "" : parts [1];
break;
case "publickeytoken":
var pk_token = parts [1];
if (pk_token == "null")
break;
name.PublicKeyToken = new byte [pk_token.Length / 2];
for (int j = 0; j < name.PublicKeyToken.Length; j++)
name.PublicKeyToken [j] = Byte.Parse (pk_token.Substring (j * 2, 2), NumberStyles.HexNumber);
break;
}
}
return name;
}
public AssemblyHashAlgorithm HashAlgorithm {
get { return hash_algorithm; }
set { hash_algorithm = value; }
}
public virtual byte [] Hash {
get { return hash; }
set { hash = value; }
}
public MetadataToken MetadataToken {
get { return token; }
set { token = value; }
}
internal AssemblyNameReference ()
{
this.version = Mixin.ZeroVersion;
this.token = new MetadataToken (TokenType.AssemblyRef);
}
public AssemblyNameReference (string name, Version version)
{
Mixin.CheckName (name);
this.name = name;
this.version = Mixin.CheckVersion (version);
this.hash_algorithm = AssemblyHashAlgorithm.None;
this.token = new MetadataToken (TokenType.AssemblyRef);
}
public override string ToString ()
{
return this.FullName;
}
}
partial class Mixin {
public static Version ZeroVersion = new Version (0, 0, 0 ,0);
public static Version CheckVersion (Version version)
{
if (version == null)
return ZeroVersion;
if (version.Build == -1)
return new Version (version.Major, version.Minor, 0, 0);
if (version.Revision == -1)
return new Version (version.Major, version.Minor, version.Build, 0);
return version;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Text;
using Mono.Collections.Generic;
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
using Mono.Cecil.PE;
using RVA = System.UInt32;
namespace Mono.Cecil {
abstract class ModuleReader {
readonly protected ModuleDefinition module;
protected ModuleReader (Image image, ReadingMode mode)
{
this.module = new ModuleDefinition (image);
this.module.ReadingMode = mode;
}
protected abstract void ReadModule ();
public abstract void ReadSymbols (ModuleDefinition module);
protected void ReadModuleManifest (MetadataReader reader)
{
reader.Populate (module);
ReadAssembly (reader);
}
void ReadAssembly (MetadataReader reader)
{
var name = reader.ReadAssemblyNameDefinition ();
if (name == null) {
module.kind = ModuleKind.NetModule;
return;
}
var assembly = new AssemblyDefinition ();
assembly.Name = name;
module.assembly = assembly;
assembly.main_module = module;
}
public static ModuleDefinition CreateModule (Image image, ReaderParameters parameters)
{
var reader = CreateModuleReader (image, parameters.ReadingMode);
var module = reader.module;
if (parameters.assembly_resolver != null)
module.assembly_resolver = Disposable.NotOwned (parameters.assembly_resolver);
if (parameters.metadata_resolver != null)
module.metadata_resolver = parameters.metadata_resolver;
#if !READ_ONLY
if (parameters.metadata_importer_provider != null)
module.metadata_importer = parameters.metadata_importer_provider.GetMetadataImporter (module);
if (parameters.reflection_importer_provider != null)
module.reflection_importer = parameters.reflection_importer_provider.GetReflectionImporter (module);
#endif
GetMetadataKind (module, parameters);
reader.ReadModule ();
ReadSymbols (module, parameters);
reader.ReadSymbols (module);
if (parameters.ReadingMode == ReadingMode.Immediate)
module.MetadataSystem.Clear ();
return module;
}
static void ReadSymbols (ModuleDefinition module, ReaderParameters parameters)
{
var symbol_reader_provider = parameters.SymbolReaderProvider;
if (symbol_reader_provider == null && parameters.ReadSymbols)
symbol_reader_provider = new DefaultSymbolReaderProvider ();
if (symbol_reader_provider != null) {
module.SymbolReaderProvider = symbol_reader_provider;
var reader = parameters.SymbolStream != null
? symbol_reader_provider.GetSymbolReader (module, parameters.SymbolStream)
: symbol_reader_provider.GetSymbolReader (module, module.FileName);
if (reader != null)
module.ReadSymbols (reader, parameters.ThrowIfSymbolsAreNotMatching);
}
if (module.Image.HasDebugTables ())
module.ReadSymbols (new PortablePdbReader (module.Image, module));
}
static void GetMetadataKind (ModuleDefinition module, ReaderParameters parameters)
{
if (!parameters.ApplyWindowsRuntimeProjections) {
module.MetadataKind = MetadataKind.Ecma335;
return;
}
var runtime_version = module.RuntimeVersion;
if (!runtime_version.Contains ("WindowsRuntime"))
module.MetadataKind = MetadataKind.Ecma335;
else if (runtime_version.Contains ("CLR"))
module.MetadataKind = MetadataKind.ManagedWindowsMetadata;
else
module.MetadataKind = MetadataKind.WindowsMetadata;
}
static ModuleReader CreateModuleReader (Image image, ReadingMode mode)
{
switch (mode) {
case ReadingMode.Immediate:
return new ImmediateModuleReader (image);
case ReadingMode.Deferred:
return new DeferredModuleReader (image);
default:
throw new ArgumentException ();
}
}
}
sealed class ImmediateModuleReader : ModuleReader {
bool resolve_attributes;
public ImmediateModuleReader (Image image)
: base (image, ReadingMode.Immediate)
{
}
protected override void ReadModule ()
{
this.module.Read (this.module, (module, reader) => {
ReadModuleManifest (reader);
ReadModule (module, resolve_attributes: true);
});
}
public void ReadModule (ModuleDefinition module, bool resolve_attributes)
{
this.resolve_attributes = resolve_attributes;
if (module.HasAssemblyReferences)
Mixin.Read (module.AssemblyReferences);
if (module.HasResources)
Mixin.Read (module.Resources);
if (module.HasModuleReferences)
Mixin.Read (module.ModuleReferences);
if (module.HasTypes)
ReadTypes (module.Types);
if (module.HasExportedTypes)
Mixin.Read (module.ExportedTypes);
ReadCustomAttributes (module);
var assembly = module.Assembly;
if (assembly == null)
return;
ReadCustomAttributes (assembly);
ReadSecurityDeclarations (assembly);
}
void ReadTypes (Collection<TypeDefinition> types)
{
for (int i = 0; i < types.Count; i++)
ReadType (types [i]);
}
void ReadType (TypeDefinition type)
{
ReadGenericParameters (type);
if (type.HasInterfaces)
ReadInterfaces (type);
if (type.HasNestedTypes)
ReadTypes (type.NestedTypes);
if (type.HasLayoutInfo)
Mixin.Read (type.ClassSize);
if (type.HasFields)
ReadFields (type);
if (type.HasMethods)
ReadMethods (type);
if (type.HasProperties)
ReadProperties (type);
if (type.HasEvents)
ReadEvents (type);
ReadSecurityDeclarations (type);
ReadCustomAttributes (type);
}
void ReadInterfaces (TypeDefinition type)
{
var interfaces = type.Interfaces;
for (int i = 0; i < interfaces.Count; i++)
ReadCustomAttributes (interfaces [i]);
}
void ReadGenericParameters (IGenericParameterProvider provider)
{
if (!provider.HasGenericParameters)
return;
var parameters = provider.GenericParameters;
for (int i = 0; i < parameters.Count; i++) {
var parameter = parameters [i];
if (parameter.HasConstraints)
Mixin.Read (parameter.Constraints);
ReadCustomAttributes (parameter);
}
}
void ReadSecurityDeclarations (ISecurityDeclarationProvider provider)
{
if (!provider.HasSecurityDeclarations)
return;
var security_declarations = provider.SecurityDeclarations;
if (!resolve_attributes)
return;
for (int i = 0; i < security_declarations.Count; i++) {
var security_declaration = security_declarations [i];
Mixin.Read (security_declaration.SecurityAttributes);
}
}
void ReadCustomAttributes (ICustomAttributeProvider provider)
{
if (!provider.HasCustomAttributes)
return;
var custom_attributes = provider.CustomAttributes;
if (!resolve_attributes)
return;
for (int i = 0; i < custom_attributes.Count; i++) {
var custom_attribute = custom_attributes [i];
Mixin.Read (custom_attribute.ConstructorArguments);
}
}
void ReadFields (TypeDefinition type)
{
var fields = type.Fields;
for (int i = 0; i < fields.Count; i++) {
var field = fields [i];
if (field.HasConstant)
Mixin.Read (field.Constant);
if (field.HasLayoutInfo)
Mixin.Read (field.Offset);
if (field.RVA > 0)
Mixin.Read (field.InitialValue);
if (field.HasMarshalInfo)
Mixin.Read (field.MarshalInfo);
ReadCustomAttributes (field);
}
}
void ReadMethods (TypeDefinition type)
{
var methods = type.Methods;
for (int i = 0; i < methods.Count; i++) {
var method = methods [i];
ReadGenericParameters (method);
if (method.HasParameters)
ReadParameters (method);
if (method.HasOverrides)
Mixin.Read (method.Overrides);
if (method.IsPInvokeImpl)
Mixin.Read (method.PInvokeInfo);
ReadSecurityDeclarations (method);
ReadCustomAttributes (method);
var return_type = method.MethodReturnType;
if (return_type.HasConstant)
Mixin.Read (return_type.Constant);
if (return_type.HasMarshalInfo)
Mixin.Read (return_type.MarshalInfo);
ReadCustomAttributes (return_type);
}
}
void ReadParameters (MethodDefinition method)
{
var parameters = method.Parameters;
for (int i = 0; i < parameters.Count; i++) {
var parameter = parameters [i];
if (parameter.HasConstant)
Mixin.Read (parameter.Constant);
if (parameter.HasMarshalInfo)
Mixin.Read (parameter.MarshalInfo);
ReadCustomAttributes (parameter);
}
}
void ReadProperties (TypeDefinition type)
{
var properties = type.Properties;
for (int i = 0; i < properties.Count; i++) {
var property = properties [i];
Mixin.Read (property.GetMethod);
if (property.HasConstant)
Mixin.Read (property.Constant);
ReadCustomAttributes (property);
}
}
void ReadEvents (TypeDefinition type)
{
var events = type.Events;
for (int i = 0; i < events.Count; i++) {
var @event = events [i];
Mixin.Read (@event.AddMethod);
ReadCustomAttributes (@event);
}
}
public override void ReadSymbols (ModuleDefinition module)
{
if (module.symbol_reader == null)
return;
ReadTypesSymbols (module.Types, module.symbol_reader);
}
void ReadTypesSymbols (Collection<TypeDefinition> types, ISymbolReader symbol_reader)
{
for (int i = 0; i < types.Count; i++) {
var type = types [i];
if (type.HasNestedTypes)
ReadTypesSymbols (type.NestedTypes, symbol_reader);
if (type.HasMethods)
ReadMethodsSymbols (type, symbol_reader);
}
}
void ReadMethodsSymbols (TypeDefinition type, ISymbolReader symbol_reader)
{
var methods = type.Methods;
for (int i = 0; i < methods.Count; i++) {
var method = methods [i];
if (method.HasBody && method.token.RID != 0 && method.debug_info == null)
method.debug_info = symbol_reader.Read (method);
}
}
}
sealed class DeferredModuleReader : ModuleReader {
public DeferredModuleReader (Image image)
: base (image, ReadingMode.Deferred)
{
}
protected override void ReadModule ()
{
this.module.Read (this.module, (_, reader) => ReadModuleManifest (reader));
}
public override void ReadSymbols (ModuleDefinition module)
{
}
}
sealed class MetadataReader : ByteBuffer {
readonly internal Image image;
readonly internal ModuleDefinition module;
readonly internal MetadataSystem metadata;
internal CodeReader code;
internal IGenericContext context;
readonly MetadataReader metadata_reader;
public MetadataReader (ModuleDefinition module)
: base (module.Image.TableHeap.data)
{
this.image = module.Image;
this.module = module;
this.metadata = module.MetadataSystem;
this.code = new CodeReader (this);
}
public MetadataReader (Image image, ModuleDefinition module, MetadataReader metadata_reader)
: base (image.TableHeap.data)
{
this.image = image;
this.module = module;
this.metadata = module.MetadataSystem;
this.metadata_reader = metadata_reader;
}
int GetCodedIndexSize (CodedIndex index)
{
return image.GetCodedIndexSize (index);
}
uint ReadByIndexSize (int size)
{
if (size == 4)
return ReadUInt32 ();
else
return ReadUInt16 ();
}
byte [] ReadBlob ()
{
var blob_heap = image.BlobHeap;
if (blob_heap == null) {
position += 2;
return Empty<byte>.Array;
}
return blob_heap.Read (ReadBlobIndex ());
}
byte [] ReadBlob (uint signature)
{
var blob_heap = image.BlobHeap;
if (blob_heap == null)
return Empty<byte>.Array;
return blob_heap.Read (signature);
}
uint ReadBlobIndex ()
{
var blob_heap = image.BlobHeap;
return ReadByIndexSize (blob_heap != null ? blob_heap.IndexSize : 2);
}
void GetBlobView (uint signature, out byte [] blob, out int index, out int count)
{
var blob_heap = image.BlobHeap;
if (blob_heap == null) {
blob = null;
index = count = 0;
return;
}
blob_heap.GetView (signature, out blob, out index, out count);
}
string ReadString ()
{
return image.StringHeap.Read (ReadByIndexSize (image.StringHeap.IndexSize));
}
uint ReadStringIndex ()
{
return ReadByIndexSize (image.StringHeap.IndexSize);
}
Guid ReadGuid ()
{
return image.GuidHeap.Read (ReadByIndexSize (image.GuidHeap.IndexSize));
}
uint ReadTableIndex (Table table)
{
return ReadByIndexSize (image.GetTableIndexSize (table));
}
MetadataToken ReadMetadataToken (CodedIndex index)
{
return index.GetMetadataToken (ReadByIndexSize (GetCodedIndexSize (index)));
}
int MoveTo (Table table)
{
var info = image.TableHeap [table];
if (info.Length != 0)
this.position = (int) info.Offset;
return (int) info.Length;
}
bool MoveTo (Table table, uint row)
{
var info = image.TableHeap [table];
var length = info.Length;
if (length == 0 || row > length)
return false;
this.position = (int) (info.Offset + (info.RowSize * (row - 1)));
return true;
}
public AssemblyNameDefinition ReadAssemblyNameDefinition ()
{
if (MoveTo (Table.Assembly) == 0)
return null;
var name = new AssemblyNameDefinition ();
name.HashAlgorithm = (AssemblyHashAlgorithm) ReadUInt32 ();
PopulateVersionAndFlags (name);
name.PublicKey = ReadBlob ();
PopulateNameAndCulture (name);
return name;
}
public ModuleDefinition Populate (ModuleDefinition module)
{
if (MoveTo (Table.Module) == 0)
return module;
Advance (2); // Generation
module.Name = ReadString ();
module.Mvid = ReadGuid ();
return module;
}
void InitializeAssemblyReferences ()
{
if (metadata.AssemblyReferences != null)
return;
int length = MoveTo (Table.AssemblyRef);
var references = metadata.AssemblyReferences = new AssemblyNameReference [length];
for (uint i = 0; i < length; i++) {
var reference = new AssemblyNameReference ();
reference.token = new MetadataToken (TokenType.AssemblyRef, i + 1);
PopulateVersionAndFlags (reference);
var key_or_token = ReadBlob ();
if (reference.HasPublicKey)
reference.PublicKey = key_or_token;
else
reference.PublicKeyToken = key_or_token;
PopulateNameAndCulture (reference);
reference.Hash = ReadBlob ();
references [i] = reference;
}
}
public Collection<AssemblyNameReference> ReadAssemblyReferences ()
{
InitializeAssemblyReferences ();
var references = new Collection<AssemblyNameReference> (metadata.AssemblyReferences);
if (module.IsWindowsMetadata ())
module.Projections.AddVirtualReferences (references);
return references;
}
public MethodDefinition ReadEntryPoint ()
{
if (module.Image.EntryPointToken == 0)
return null;
var token = new MetadataToken (module.Image.EntryPointToken);
return GetMethodDefinition (token.RID);
}
public Collection<ModuleDefinition> ReadModules ()
{
var modules = new Collection<ModuleDefinition> (1);
modules.Add (this.module);
int length = MoveTo (Table.File);
for (uint i = 1; i <= length; i++) {
var attributes = (FileAttributes) ReadUInt32 ();
var name = ReadString ();
ReadBlobIndex ();
if (attributes != FileAttributes.ContainsMetaData)
continue;
var parameters = new ReaderParameters {
ReadingMode = module.ReadingMode,
SymbolReaderProvider = module.SymbolReaderProvider,
AssemblyResolver = module.AssemblyResolver
};
modules.Add (ModuleDefinition.ReadModule (
GetModuleFileName (name), parameters));
}
return modules;
}
string GetModuleFileName (string name)
{
if (module.FileName == null)
throw new NotSupportedException ();
var path = Path.GetDirectoryName (module.FileName);
return Path.Combine (path, name);
}
void InitializeModuleReferences ()
{
if (metadata.ModuleReferences != null)
return;
int length = MoveTo (Table.ModuleRef);
var references = metadata.ModuleReferences = new ModuleReference [length];
for (uint i = 0; i < length; i++) {
var reference = new ModuleReference (ReadString ());
reference.token = new MetadataToken (TokenType.ModuleRef, i + 1);
references [i] = reference;
}
}
public Collection<ModuleReference> ReadModuleReferences ()
{
InitializeModuleReferences ();
return new Collection<ModuleReference> (metadata.ModuleReferences);
}
public bool HasFileResource ()
{
int length = MoveTo (Table.File);
if (length == 0)
return false;
for (uint i = 1; i <= length; i++)
if (ReadFileRecord (i).Col1 == FileAttributes.ContainsNoMetaData)
return true;
return false;
}
public Collection<Resource> ReadResources ()
{
int length = MoveTo (Table.ManifestResource);
var resources = new Collection<Resource> (length);
for (int i = 1; i <= length; i++) {
var offset = ReadUInt32 ();
var flags = (ManifestResourceAttributes) ReadUInt32 ();
var name = ReadString ();
var implementation = ReadMetadataToken (CodedIndex.Implementation);
Resource resource;
if (implementation.RID == 0) {
resource = new EmbeddedResource (name, flags, offset, this);
} else if (implementation.TokenType == TokenType.AssemblyRef) {
resource = new AssemblyLinkedResource (name, flags) {
Assembly = (AssemblyNameReference) GetTypeReferenceScope (implementation),
};
} else if (implementation.TokenType == TokenType.File) {
var file_record = ReadFileRecord (implementation.RID);
resource = new LinkedResource (name, flags) {
File = file_record.Col2,
hash = ReadBlob (file_record.Col3)
};
} else
continue;
resources.Add (resource);
}
return resources;
}
Row<FileAttributes, string, uint> ReadFileRecord (uint rid)
{
var position = this.position;
if (!MoveTo (Table.File, rid))
throw new ArgumentException ();
var record = new Row<FileAttributes, string, uint> (
(FileAttributes) ReadUInt32 (),
ReadString (),
ReadBlobIndex ());
this.position = position;
return record;
}
public byte [] GetManagedResource (uint offset)
{
return image.GetReaderAt (image.Resources.VirtualAddress, offset, (o, reader) => {
reader.Advance ((int) o);
return reader.ReadBytes (reader.ReadInt32 ());
}) ?? Empty<byte>.Array;
}
void PopulateVersionAndFlags (AssemblyNameReference name)
{
name.Version = new Version (
ReadUInt16 (),
ReadUInt16 (),
ReadUInt16 (),
ReadUInt16 ());
name.Attributes = (AssemblyAttributes) ReadUInt32 ();
}
void PopulateNameAndCulture (AssemblyNameReference name)
{
name.Name = ReadString ();
name.Culture = ReadString ();
}
public TypeDefinitionCollection ReadTypes ()
{
InitializeTypeDefinitions ();
var mtypes = metadata.Types;
var type_count = mtypes.Length - metadata.NestedTypes.Count;
var types = new TypeDefinitionCollection (module, type_count);
for (int i = 0; i < mtypes.Length; i++) {
var type = mtypes [i];
if (IsNested (type.Attributes))
continue;
types.Add (type);
}
if (image.HasTable (Table.MethodPtr) || image.HasTable (Table.FieldPtr))
CompleteTypes ();
return types;
}
void CompleteTypes ()
{
var types = metadata.Types;
for (int i = 0; i < types.Length; i++) {
var type = types [i];
Mixin.Read (type.Fields);
Mixin.Read (type.Methods);
}
}
void InitializeTypeDefinitions ()
{
if (metadata.Types != null)
return;
InitializeNestedTypes ();
InitializeFields ();
InitializeMethods ();
int length = MoveTo (Table.TypeDef);
var types = metadata.Types = new TypeDefinition [length];
for (uint i = 0; i < length; i++) {
if (types [i] != null)
continue;
types [i] = ReadType (i + 1);
}
if (module.IsWindowsMetadata ()) {
for (uint i = 0; i < length; i++) {
WindowsRuntimeProjections.Project (types [i]);
}
}
}
static bool IsNested (TypeAttributes attributes)
{
switch (attributes & TypeAttributes.VisibilityMask) {
case TypeAttributes.NestedAssembly:
case TypeAttributes.NestedFamANDAssem:
case TypeAttributes.NestedFamily:
case TypeAttributes.NestedFamORAssem:
case TypeAttributes.NestedPrivate:
case TypeAttributes.NestedPublic:
return true;
default:
return false;
}
}
public bool HasNestedTypes (TypeDefinition type)
{
Collection<uint> mapping;
InitializeNestedTypes ();
if (!metadata.TryGetNestedTypeMapping (type, out mapping))
return false;
return mapping.Count > 0;
}
public Collection<TypeDefinition> ReadNestedTypes (TypeDefinition type)
{
InitializeNestedTypes ();
Collection<uint> mapping;
if (!metadata.TryGetNestedTypeMapping (type, out mapping))
return new MemberDefinitionCollection<TypeDefinition> (type);
var nested_types = new MemberDefinitionCollection<TypeDefinition> (type, mapping.Count);
for (int i = 0; i < mapping.Count; i++) {
var nested_type = GetTypeDefinition (mapping [i]);
if (nested_type != null)
nested_types.Add (nested_type);
}
metadata.RemoveNestedTypeMapping (type);
return nested_types;
}
void InitializeNestedTypes ()
{
if (metadata.NestedTypes != null)
return;
var length = MoveTo (Table.NestedClass);
metadata.NestedTypes = new Dictionary<uint, Collection<uint>> (length);
metadata.ReverseNestedTypes = new Dictionary<uint, uint> (length);
if (length == 0)
return;
for (int i = 1; i <= length; i++) {
var nested = ReadTableIndex (Table.TypeDef);
var declaring = ReadTableIndex (Table.TypeDef);
AddNestedMapping (declaring, nested);
}
}
void AddNestedMapping (uint declaring, uint nested)
{
metadata.SetNestedTypeMapping (declaring, AddMapping (metadata.NestedTypes, declaring, nested));
metadata.SetReverseNestedTypeMapping (nested, declaring);
}
static Collection<TValue> AddMapping<TKey, TValue> (Dictionary<TKey, Collection<TValue>> cache, TKey key, TValue value)
{
Collection<TValue> mapped;
if (!cache.TryGetValue (key, out mapped)) {
mapped = new Collection<TValue> ();
}
mapped.Add (value);
return mapped;
}
TypeDefinition ReadType (uint rid)
{
if (!MoveTo (Table.TypeDef, rid))
return null;
var attributes = (TypeAttributes) ReadUInt32 ();
var name = ReadString ();
var @namespace = ReadString ();
var type = new TypeDefinition (@namespace, name, attributes);
type.token = new MetadataToken (TokenType.TypeDef, rid);
type.scope = module;
type.module = module;
metadata.AddTypeDefinition (type);
this.context = type;
type.BaseType = GetTypeDefOrRef (ReadMetadataToken (CodedIndex.TypeDefOrRef));
type.fields_range = ReadListRange (rid, Table.TypeDef, Table.Field);
type.methods_range = ReadListRange (rid, Table.TypeDef, Table.Method);
if (IsNested (attributes))
type.DeclaringType = GetNestedTypeDeclaringType (type);
return type;
}
TypeDefinition GetNestedTypeDeclaringType (TypeDefinition type)
{
uint declaring_rid;
if (!metadata.TryGetReverseNestedTypeMapping (type, out declaring_rid))
return null;
metadata.RemoveReverseNestedTypeMapping (type);
return GetTypeDefinition (declaring_rid);
}
Range ReadListRange (uint current_index, Table current, Table target)
{
var list = new Range ();
var start = ReadTableIndex (target);
if (start == 0)
return list;
uint next_index;
var current_table = image.TableHeap [current];
if (current_index == current_table.Length)
next_index = image.TableHeap [target].Length + 1;
else {
var position = this.position;
this.position += (int) (current_table.RowSize - image.GetTableIndexSize (target));
next_index = ReadTableIndex (target);
this.position = position;
}
list.Start = start;
list.Length = next_index - start;
return list;
}
public Row<short, int> ReadTypeLayout (TypeDefinition type)
{
InitializeTypeLayouts ();
Row<ushort, uint> class_layout;
var rid = type.token.RID;
if (!metadata.ClassLayouts.TryGetValue (rid, out class_layout))
return new Row<short, int> (Mixin.NoDataMarker, Mixin.NoDataMarker);
type.PackingSize = (short) class_layout.Col1;
type.ClassSize = (int) class_layout.Col2;
metadata.ClassLayouts.Remove (rid);
return new Row<short, int> ((short) class_layout.Col1, (int) class_layout.Col2);
}
void InitializeTypeLayouts ()
{
if (metadata.ClassLayouts != null)
return;
int length = MoveTo (Table.ClassLayout);
var class_layouts = metadata.ClassLayouts = new Dictionary<uint, Row<ushort, uint>> (length);
for (uint i = 0; i < length; i++) {
var packing_size = ReadUInt16 ();
var class_size = ReadUInt32 ();
var parent = ReadTableIndex (Table.TypeDef);
class_layouts.Add (parent, new Row<ushort, uint> (packing_size, class_size));
}
}
public TypeReference GetTypeDefOrRef (MetadataToken token)
{
return (TypeReference) LookupToken (token);
}
public TypeDefinition GetTypeDefinition (uint rid)
{
InitializeTypeDefinitions ();
var type = metadata.GetTypeDefinition (rid);
if (type != null)
return type;
type = ReadTypeDefinition (rid);
if (module.IsWindowsMetadata ())
WindowsRuntimeProjections.Project (type);
return type;
}
TypeDefinition ReadTypeDefinition (uint rid)
{
if (!MoveTo (Table.TypeDef, rid))
return null;
return ReadType (rid);
}
void InitializeTypeReferences ()
{
if (metadata.TypeReferences != null)
return;
metadata.TypeReferences = new TypeReference [image.GetTableLength (Table.TypeRef)];
}
public TypeReference GetTypeReference (string scope, string full_name)
{
InitializeTypeReferences ();
var length = metadata.TypeReferences.Length;
for (uint i = 1; i <= length; i++) {
var type = GetTypeReference (i);
if (type.FullName != full_name)
continue;
if (string.IsNullOrEmpty (scope))
return type;
if (type.Scope.Name == scope)
return type;
}
return null;
}
TypeReference GetTypeReference (uint rid)
{
InitializeTypeReferences ();
var type = metadata.GetTypeReference (rid);
if (type != null)
return type;
return ReadTypeReference (rid);
}
TypeReference ReadTypeReference (uint rid)
{
if (!MoveTo (Table.TypeRef, rid))
return null;
TypeReference declaring_type = null;
IMetadataScope scope;
var scope_token = ReadMetadataToken (CodedIndex.ResolutionScope);
var name = ReadString ();
var @namespace = ReadString ();
var type = new TypeReference (
@namespace,
name,
module,
null);
type.token = new MetadataToken (TokenType.TypeRef, rid);
metadata.AddTypeReference (type);
if (scope_token.TokenType == TokenType.TypeRef) {
declaring_type = GetTypeDefOrRef (scope_token);
scope = declaring_type != null
? declaring_type.Scope
: module;
} else
scope = GetTypeReferenceScope (scope_token);
type.scope = scope;
type.DeclaringType = declaring_type;
MetadataSystem.TryProcessPrimitiveTypeReference (type);
if (type.Module.IsWindowsMetadata ())
WindowsRuntimeProjections.Project (type);
return type;
}
IMetadataScope GetTypeReferenceScope (MetadataToken scope)
{
if (scope.TokenType == TokenType.Module)
return module;
IMetadataScope[] scopes;
switch (scope.TokenType) {
case TokenType.AssemblyRef:
InitializeAssemblyReferences ();
scopes = metadata.AssemblyReferences;
break;
case TokenType.ModuleRef:
InitializeModuleReferences ();
scopes = metadata.ModuleReferences;
break;
default:
throw new NotSupportedException ();
}
var index = scope.RID - 1;
if (index < 0 || index >= scopes.Length)
return null;
return scopes [index];
}
public IEnumerable<TypeReference> GetTypeReferences ()
{
InitializeTypeReferences ();
var length = image.GetTableLength (Table.TypeRef);
var type_references = new TypeReference [length];
for (uint i = 1; i <= length; i++)
type_references [i - 1] = GetTypeReference (i);
return type_references;
}
TypeReference GetTypeSpecification (uint rid)
{
if (!MoveTo (Table.TypeSpec, rid))
return null;
var reader = ReadSignature (ReadBlobIndex ());
var type = reader.ReadTypeSignature ();
if (type.token.RID == 0)
type.token = new MetadataToken (TokenType.TypeSpec, rid);
return type;
}
SignatureReader ReadSignature (uint signature)
{
return new SignatureReader (signature, this);
}
public bool HasInterfaces (TypeDefinition type)
{
InitializeInterfaces ();
Collection<Row<uint, MetadataToken>> mapping;
return metadata.TryGetInterfaceMapping (type, out mapping);
}
public InterfaceImplementationCollection ReadInterfaces (TypeDefinition type)
{
InitializeInterfaces ();
Collection<Row<uint, MetadataToken>> mapping;
if (!metadata.TryGetInterfaceMapping (type, out mapping))
return new InterfaceImplementationCollection (type);
var interfaces = new InterfaceImplementationCollection (type, mapping.Count);
this.context = type;
for (int i = 0; i < mapping.Count; i++) {
interfaces.Add (
new InterfaceImplementation (
GetTypeDefOrRef (mapping [i].Col2),
new MetadataToken(TokenType.InterfaceImpl, mapping [i].Col1)));
}
metadata.RemoveInterfaceMapping (type);
return interfaces;
}
void InitializeInterfaces ()
{
if (metadata.Interfaces != null)
return;
int length = MoveTo (Table.InterfaceImpl);
metadata.Interfaces = new Dictionary<uint, Collection<Row<uint, MetadataToken>>> (length);
for (uint i = 1; i <= length; i++) {
var type = ReadTableIndex (Table.TypeDef);
var @interface = ReadMetadataToken (CodedIndex.TypeDefOrRef);
AddInterfaceMapping (type, new Row<uint, MetadataToken> (i, @interface));
}
}
void AddInterfaceMapping (uint type, Row<uint, MetadataToken> @interface)
{
metadata.SetInterfaceMapping (type, AddMapping (metadata.Interfaces, type, @interface));
}
public Collection<FieldDefinition> ReadFields (TypeDefinition type)
{
var fields_range = type.fields_range;
if (fields_range.Length == 0)
return new MemberDefinitionCollection<FieldDefinition> (type);
var fields = new MemberDefinitionCollection<FieldDefinition> (type, (int) fields_range.Length);
this.context = type;
if (!MoveTo (Table.FieldPtr, fields_range.Start)) {
if (!MoveTo (Table.Field, fields_range.Start))
return fields;
for (uint i = 0; i < fields_range.Length; i++)
ReadField (fields_range.Start + i, fields);
} else
ReadPointers (Table.FieldPtr, Table.Field, fields_range, fields, ReadField);
return fields;
}
void ReadField (uint field_rid, Collection<FieldDefinition> fields)
{
var attributes = (FieldAttributes) ReadUInt16 ();
var name = ReadString ();
var signature = ReadBlobIndex ();
var field = new FieldDefinition (name, attributes, ReadFieldType (signature));
field.token = new MetadataToken (TokenType.Field, field_rid);
metadata.AddFieldDefinition (field);
if (IsDeleted (field))
return;
fields.Add (field);
if (module.IsWindowsMetadata ())
WindowsRuntimeProjections.Project (field);
}
void InitializeFields ()
{
if (metadata.Fields != null)
return;
metadata.Fields = new FieldDefinition [image.GetTableLength (Table.Field)];
}
TypeReference ReadFieldType (uint signature)
{
var reader = ReadSignature (signature);
const byte field_sig = 0x6;
if (reader.ReadByte () != field_sig)
throw new NotSupportedException ();
return reader.ReadTypeSignature ();
}
public int ReadFieldRVA (FieldDefinition field)
{
InitializeFieldRVAs ();
var rid = field.token.RID;
RVA rva;
if (!metadata.FieldRVAs.TryGetValue (rid, out rva))
return 0;
var size = GetFieldTypeSize (field.FieldType);
if (size == 0 || rva == 0)
return 0;
metadata.FieldRVAs.Remove (rid);
field.InitialValue = GetFieldInitializeValue (size, rva);
return (int) rva;
}
byte [] GetFieldInitializeValue (int size, RVA rva)
{
return image.GetReaderAt (rva, size, (s, reader) => reader.ReadBytes (s)) ?? Empty<byte>.Array;
}
static int GetFieldTypeSize (TypeReference type)
{
int size = 0;
switch (type.etype) {
case ElementType.Boolean:
case ElementType.U1:
case ElementType.I1:
size = 1;
break;
case ElementType.U2:
case ElementType.I2:
case ElementType.Char:
size = 2;
break;
case ElementType.U4:
case ElementType.I4:
case ElementType.R4:
size = 4;
break;
case ElementType.U8:
case ElementType.I8:
case ElementType.R8:
size = 8;
break;
case ElementType.Ptr:
case ElementType.FnPtr:
size = IntPtr.Size;
break;
case ElementType.CModOpt:
case ElementType.CModReqD:
return GetFieldTypeSize (((IModifierType) type).ElementType);
default:
var field_type = type.Resolve ();
if (field_type != null && field_type.HasLayoutInfo)
size = field_type.ClassSize;
break;
}
return size;
}
void InitializeFieldRVAs ()
{
if (metadata.FieldRVAs != null)
return;
int length = MoveTo (Table.FieldRVA);
var field_rvas = metadata.FieldRVAs = new Dictionary<uint, uint> (length);
for (int i = 0; i < length; i++) {
var rva = ReadUInt32 ();
var field = ReadTableIndex (Table.Field);
field_rvas.Add (field, rva);
}
}
public int ReadFieldLayout (FieldDefinition field)
{
InitializeFieldLayouts ();
var rid = field.token.RID;
uint offset;
if (!metadata.FieldLayouts.TryGetValue (rid, out offset))
return Mixin.NoDataMarker;
metadata.FieldLayouts.Remove (rid);
return (int) offset;
}
void InitializeFieldLayouts ()
{
if (metadata.FieldLayouts != null)
return;
int length = MoveTo (Table.FieldLayout);
var field_layouts = metadata.FieldLayouts = new Dictionary<uint, uint> (length);
for (int i = 0; i < length; i++) {
var offset = ReadUInt32 ();
var field = ReadTableIndex (Table.Field);
field_layouts.Add (field, offset);
}
}
public bool HasEvents (TypeDefinition type)
{
InitializeEvents ();
Range range;
if (!metadata.TryGetEventsRange (type, out range))
return false;
return range.Length > 0;
}
public Collection<EventDefinition> ReadEvents (TypeDefinition type)
{
InitializeEvents ();
Range range;
if (!metadata.TryGetEventsRange (type, out range))
return new MemberDefinitionCollection<EventDefinition> (type);
var events = new MemberDefinitionCollection<EventDefinition> (type, (int) range.Length);
metadata.RemoveEventsRange (type);
if (range.Length == 0)
return events;
this.context = type;
if (!MoveTo (Table.EventPtr, range.Start)) {
if (!MoveTo (Table.Event, range.Start))
return events;
for (uint i = 0; i < range.Length; i++)
ReadEvent (range.Start + i, events);
} else
ReadPointers (Table.EventPtr, Table.Event, range, events, ReadEvent);
return events;
}
void ReadEvent (uint event_rid, Collection<EventDefinition> events)
{
var attributes = (EventAttributes) ReadUInt16 ();
var name = ReadString ();
var event_type = GetTypeDefOrRef (ReadMetadataToken (CodedIndex.TypeDefOrRef));
var @event = new EventDefinition (name, attributes, event_type);
@event.token = new MetadataToken (TokenType.Event, event_rid);
if (IsDeleted (@event))
return;
events.Add (@event);
}
void InitializeEvents ()
{
if (metadata.Events != null)
return;
int length = MoveTo (Table.EventMap);
metadata.Events = new Dictionary<uint, Range> (length);
for (uint i = 1; i <= length; i++) {
var type_rid = ReadTableIndex (Table.TypeDef);
Range events_range = ReadListRange (i, Table.EventMap, Table.Event);
metadata.AddEventsRange (type_rid, events_range);
}
}
public bool HasProperties (TypeDefinition type)
{
InitializeProperties ();
Range range;
if (!metadata.TryGetPropertiesRange (type, out range))
return false;
return range.Length > 0;
}
public Collection<PropertyDefinition> ReadProperties (TypeDefinition type)
{
InitializeProperties ();
Range range;
if (!metadata.TryGetPropertiesRange (type, out range))
return new MemberDefinitionCollection<PropertyDefinition> (type);
metadata.RemovePropertiesRange (type);
var properties = new MemberDefinitionCollection<PropertyDefinition> (type, (int) range.Length);
if (range.Length == 0)
return properties;
this.context = type;
if (!MoveTo (Table.PropertyPtr, range.Start)) {
if (!MoveTo (Table.Property, range.Start))
return properties;
for (uint i = 0; i < range.Length; i++)
ReadProperty (range.Start + i, properties);
} else
ReadPointers (Table.PropertyPtr, Table.Property, range, properties, ReadProperty);
return properties;
}
void ReadProperty (uint property_rid, Collection<PropertyDefinition> properties)
{
var attributes = (PropertyAttributes) ReadUInt16 ();
var name = ReadString ();
var signature = ReadBlobIndex ();
var reader = ReadSignature (signature);
const byte property_signature = 0x8;
var calling_convention = reader.ReadByte ();
if ((calling_convention & property_signature) == 0)
throw new NotSupportedException ();
var has_this = (calling_convention & 0x20) != 0;
reader.ReadCompressedUInt32 (); // count
var property = new PropertyDefinition (name, attributes, reader.ReadTypeSignature ());
property.HasThis = has_this;
property.token = new MetadataToken (TokenType.Property, property_rid);
if (IsDeleted (property))
return;
properties.Add (property);
}
void InitializeProperties ()
{
if (metadata.Properties != null)
return;
int length = MoveTo (Table.PropertyMap);
metadata.Properties = new Dictionary<uint, Range> (length);
for (uint i = 1; i <= length; i++) {
var type_rid = ReadTableIndex (Table.TypeDef);
var properties_range = ReadListRange (i, Table.PropertyMap, Table.Property);
metadata.AddPropertiesRange (type_rid, properties_range);
}
}
MethodSemanticsAttributes ReadMethodSemantics (MethodDefinition method)
{
InitializeMethodSemantics ();
Row<MethodSemanticsAttributes, MetadataToken> row;
if (!metadata.Semantics.TryGetValue (method.token.RID, out row))
return MethodSemanticsAttributes.None;
var type = method.DeclaringType;
switch (row.Col1) {
case MethodSemanticsAttributes.AddOn:
GetEvent (type, row.Col2).add_method = method;
break;
case MethodSemanticsAttributes.Fire:
GetEvent (type, row.Col2).invoke_method = method;
break;
case MethodSemanticsAttributes.RemoveOn:
GetEvent (type, row.Col2).remove_method = method;
break;
case MethodSemanticsAttributes.Getter:
GetProperty (type, row.Col2).get_method = method;
break;
case MethodSemanticsAttributes.Setter:
GetProperty (type, row.Col2).set_method = method;
break;
case MethodSemanticsAttributes.Other:
switch (row.Col2.TokenType) {
case TokenType.Event: {
var @event = GetEvent (type, row.Col2);
if (@event.other_methods == null)
@event.other_methods = new Collection<MethodDefinition> ();
@event.other_methods.Add (method);
break;
}
case TokenType.Property: {
var property = GetProperty (type, row.Col2);
if (property.other_methods == null)
property.other_methods = new Collection<MethodDefinition> ();
property.other_methods.Add (method);
break;
}
default:
throw new NotSupportedException ();
}
break;
default:
throw new NotSupportedException ();
}
metadata.Semantics.Remove (method.token.RID);
return row.Col1;
}
static EventDefinition GetEvent (TypeDefinition type, MetadataToken token)
{
if (token.TokenType != TokenType.Event)
throw new ArgumentException ();
return GetMember (type.Events, token);
}
static PropertyDefinition GetProperty (TypeDefinition type, MetadataToken token)
{
if (token.TokenType != TokenType.Property)
throw new ArgumentException ();
return GetMember (type.Properties, token);
}
static TMember GetMember<TMember> (Collection<TMember> members, MetadataToken token) where TMember : IMemberDefinition
{
for (int i = 0; i < members.Count; i++) {
var member = members [i];
if (member.MetadataToken == token)
return member;
}
throw new ArgumentException ();
}
void InitializeMethodSemantics ()
{
if (metadata.Semantics != null)
return;
int length = MoveTo (Table.MethodSemantics);
var semantics = metadata.Semantics = new Dictionary<uint, Row<MethodSemanticsAttributes, MetadataToken>> (0);
for (uint i = 0; i < length; i++) {
var attributes = (MethodSemanticsAttributes) ReadUInt16 ();
var method_rid = ReadTableIndex (Table.Method);
var association = ReadMetadataToken (CodedIndex.HasSemantics);
semantics [method_rid] = new Row<MethodSemanticsAttributes, MetadataToken> (attributes, association);
}
}
public void ReadMethods (PropertyDefinition property)
{
ReadAllSemantics (property.DeclaringType);
}
public void ReadMethods (EventDefinition @event)
{
ReadAllSemantics (@event.DeclaringType);
}
public void ReadAllSemantics (MethodDefinition method)
{
ReadAllSemantics (method.DeclaringType);
}
void ReadAllSemantics (TypeDefinition type)
{
var methods = type.Methods;
for (int i = 0; i < methods.Count; i++) {
var method = methods [i];
if (method.sem_attrs_ready)
continue;
method.sem_attrs = ReadMethodSemantics (method);
method.sem_attrs_ready = true;
}
}
public Collection<MethodDefinition> ReadMethods (TypeDefinition type)
{
var methods_range = type.methods_range;
if (methods_range.Length == 0)
return new MemberDefinitionCollection<MethodDefinition> (type);
var methods = new MemberDefinitionCollection<MethodDefinition> (type, (int) methods_range.Length);
if (!MoveTo (Table.MethodPtr, methods_range.Start)) {
if (!MoveTo (Table.Method, methods_range.Start))
return methods;
for (uint i = 0; i < methods_range.Length; i++)
ReadMethod (methods_range.Start + i, methods);
} else
ReadPointers (Table.MethodPtr, Table.Method, methods_range, methods, ReadMethod);
return methods;
}
void ReadPointers<TMember> (Table ptr, Table table, Range range, Collection<TMember> members, Action<uint, Collection<TMember>> reader)
where TMember : IMemberDefinition
{
for (uint i = 0; i < range.Length; i++) {
MoveTo (ptr, range.Start + i);
var rid = ReadTableIndex (table);
MoveTo (table, rid);
reader (rid, members);
}
}
static bool IsDeleted (IMemberDefinition member)
{
return member.IsSpecialName && member.Name == "_Deleted";
}
void InitializeMethods ()
{
if (metadata.Methods != null)
return;
metadata.Methods = new MethodDefinition [image.GetTableLength (Table.Method)];
}
void ReadMethod (uint method_rid, Collection<MethodDefinition> methods)
{
var method = new MethodDefinition ();
method.rva = ReadUInt32 ();
method.ImplAttributes = (MethodImplAttributes) ReadUInt16 ();
method.Attributes = (MethodAttributes) ReadUInt16 ();
method.Name = ReadString ();
method.token = new MetadataToken (TokenType.Method, method_rid);
if (IsDeleted (method))
return;
methods.Add (method); // attach method
var signature = ReadBlobIndex ();
var param_range = ReadListRange (method_rid, Table.Method, Table.Param);
this.context = method;
ReadMethodSignature (signature, method);
metadata.AddMethodDefinition (method);
if (param_range.Length != 0) {
var position = base.position;
ReadParameters (method, param_range);
base.position = position;
}
if (module.IsWindowsMetadata ())
WindowsRuntimeProjections.Project (method);
}
void ReadParameters (MethodDefinition method, Range param_range)
{
if (!MoveTo (Table.ParamPtr, param_range.Start)) {
if (!MoveTo (Table.Param, param_range.Start))
return;
for (uint i = 0; i < param_range.Length; i++)
ReadParameter (param_range.Start + i, method);
} else
ReadParameterPointers (method, param_range);
}
void ReadParameterPointers (MethodDefinition method, Range range)
{
for (uint i = 0; i < range.Length; i++) {
MoveTo (Table.ParamPtr, range.Start + i);
var rid = ReadTableIndex (Table.Param);
MoveTo (Table.Param, rid);
ReadParameter (rid, method);
}
}
void ReadParameter (uint param_rid, MethodDefinition method)
{
var attributes = (ParameterAttributes) ReadUInt16 ();
var sequence = ReadUInt16 ();
var name = ReadString ();
var parameter = sequence == 0
? method.MethodReturnType.Parameter
: method.Parameters [sequence - 1];
parameter.token = new MetadataToken (TokenType.Param, param_rid);
parameter.Name = name;
parameter.Attributes = attributes;
}
void ReadMethodSignature (uint signature, IMethodSignature method)
{
var reader = ReadSignature (signature);
reader.ReadMethodSignature (method);
}
public PInvokeInfo ReadPInvokeInfo (MethodDefinition method)
{
InitializePInvokes ();
Row<PInvokeAttributes, uint, uint> row;
var rid = method.token.RID;
if (!metadata.PInvokes.TryGetValue (rid, out row))
return null;
metadata.PInvokes.Remove (rid);
return new PInvokeInfo (
row.Col1,
image.StringHeap.Read (row.Col2),
module.ModuleReferences [(int) row.Col3 - 1]);
}
void InitializePInvokes ()
{
if (metadata.PInvokes != null)
return;
int length = MoveTo (Table.ImplMap);
var pinvokes = metadata.PInvokes = new Dictionary<uint, Row<PInvokeAttributes, uint, uint>> (length);
for (int i = 1; i <= length; i++) {
var attributes = (PInvokeAttributes) ReadUInt16 ();
var method = ReadMetadataToken (CodedIndex.MemberForwarded);
var name = ReadStringIndex ();
var scope = ReadTableIndex (Table.File);
if (method.TokenType != TokenType.Method)
continue;
pinvokes.Add (method.RID, new Row<PInvokeAttributes, uint, uint> (attributes, name, scope));
}
}
public bool HasGenericParameters (IGenericParameterProvider provider)
{
InitializeGenericParameters ();
Range [] ranges;
if (!metadata.TryGetGenericParameterRanges (provider, out ranges))
return false;
return RangesSize (ranges) > 0;
}
public Collection<GenericParameter> ReadGenericParameters (IGenericParameterProvider provider)
{
InitializeGenericParameters ();
Range [] ranges;
if (!metadata.TryGetGenericParameterRanges (provider, out ranges))
return new GenericParameterCollection (provider);
metadata.RemoveGenericParameterRange (provider);
var generic_parameters = new GenericParameterCollection (provider, RangesSize (ranges));
for (int i = 0; i < ranges.Length; i++)
ReadGenericParametersRange (ranges [i], provider, generic_parameters);
return generic_parameters;
}
void ReadGenericParametersRange (Range range, IGenericParameterProvider provider, GenericParameterCollection generic_parameters)
{
if (!MoveTo (Table.GenericParam, range.Start))
return;
for (uint i = 0; i < range.Length; i++) {
ReadUInt16 (); // index
var flags = (GenericParameterAttributes) ReadUInt16 ();
ReadMetadataToken (CodedIndex.TypeOrMethodDef);
var name = ReadString ();
var parameter = new GenericParameter (name, provider);
parameter.token = new MetadataToken (TokenType.GenericParam, range.Start + i);
parameter.Attributes = flags;
generic_parameters.Add (parameter);
}
}
void InitializeGenericParameters ()
{
if (metadata.GenericParameters != null)
return;
metadata.GenericParameters = InitializeRanges (
Table.GenericParam, () => {
Advance (4);
var next = ReadMetadataToken (CodedIndex.TypeOrMethodDef);
ReadStringIndex ();
return next;
});
}
Dictionary<MetadataToken, Range []> InitializeRanges (Table table, Func<MetadataToken> get_next)
{
int length = MoveTo (table);
var ranges = new Dictionary<MetadataToken, Range []> (length);
if (length == 0)
return ranges;
MetadataToken owner = MetadataToken.Zero;
Range range = new Range (1, 0);
for (uint i = 1; i <= length; i++) {
var next = get_next ();
if (i == 1) {
owner = next;
range.Length++;
} else if (next != owner) {
AddRange (ranges, owner, range);
range = new Range (i, 1);
owner = next;
} else
range.Length++;
}
AddRange (ranges, owner, range);
return ranges;
}
static void AddRange (Dictionary<MetadataToken, Range []> ranges, MetadataToken owner, Range range)
{
if (owner.RID == 0)
return;
Range [] slots;
if (!ranges.TryGetValue (owner, out slots)) {
ranges.Add (owner, new [] { range });
return;
}
ranges [owner] = slots.Add(range);
}
public bool HasGenericConstraints (GenericParameter generic_parameter)
{
InitializeGenericConstraints ();
Collection<MetadataToken> mapping;
if (!metadata.TryGetGenericConstraintMapping (generic_parameter, out mapping))
return false;
return mapping.Count > 0;
}
public Collection<TypeReference> ReadGenericConstraints (GenericParameter generic_parameter)
{
InitializeGenericConstraints ();
Collection<MetadataToken> mapping;
if (!metadata.TryGetGenericConstraintMapping (generic_parameter, out mapping))
return new Collection<TypeReference> ();
var constraints = new Collection<TypeReference> (mapping.Count);
this.context = (IGenericContext) generic_parameter.Owner;
for (int i = 0; i < mapping.Count; i++)
constraints.Add (GetTypeDefOrRef (mapping [i]));
metadata.RemoveGenericConstraintMapping (generic_parameter);
return constraints;
}
void InitializeGenericConstraints ()
{
if (metadata.GenericConstraints != null)
return;
var length = MoveTo (Table.GenericParamConstraint);
metadata.GenericConstraints = new Dictionary<uint, Collection<MetadataToken>> (length);
for (int i = 1; i <= length; i++)
AddGenericConstraintMapping (
ReadTableIndex (Table.GenericParam),
ReadMetadataToken (CodedIndex.TypeDefOrRef));
}
void AddGenericConstraintMapping (uint generic_parameter, MetadataToken constraint)
{
metadata.SetGenericConstraintMapping (
generic_parameter,
AddMapping (metadata.GenericConstraints, generic_parameter, constraint));
}
public bool HasOverrides (MethodDefinition method)
{
InitializeOverrides ();
Collection<MetadataToken> mapping;
if (!metadata.TryGetOverrideMapping (method, out mapping))
return false;
return mapping.Count > 0;
}
public Collection<MethodReference> ReadOverrides (MethodDefinition method)
{
InitializeOverrides ();
Collection<MetadataToken> mapping;
if (!metadata.TryGetOverrideMapping (method, out mapping))
return new Collection<MethodReference> ();
var overrides = new Collection<MethodReference> (mapping.Count);
this.context = method;
for (int i = 0; i < mapping.Count; i++)
overrides.Add ((MethodReference) LookupToken (mapping [i]));
metadata.RemoveOverrideMapping (method);
return overrides;
}
void InitializeOverrides ()
{
if (metadata.Overrides != null)
return;
var length = MoveTo (Table.MethodImpl);
metadata.Overrides = new Dictionary<uint, Collection<MetadataToken>> (length);
for (int i = 1; i <= length; i++) {
ReadTableIndex (Table.TypeDef);
var method = ReadMetadataToken (CodedIndex.MethodDefOrRef);
if (method.TokenType != TokenType.Method)
throw new NotSupportedException ();
var @override = ReadMetadataToken (CodedIndex.MethodDefOrRef);
AddOverrideMapping (method.RID, @override);
}
}
void AddOverrideMapping (uint method_rid, MetadataToken @override)
{
metadata.SetOverrideMapping (
method_rid,
AddMapping (metadata.Overrides, method_rid, @override));
}
public MethodBody ReadMethodBody (MethodDefinition method)
{
return code.ReadMethodBody (method);
}
public int ReadCodeSize (MethodDefinition method)
{
return code.ReadCodeSize (method);
}
public CallSite ReadCallSite (MetadataToken token)
{
if (!MoveTo (Table.StandAloneSig, token.RID))
return null;
var signature = ReadBlobIndex ();
var call_site = new CallSite ();
ReadMethodSignature (signature, call_site);
call_site.MetadataToken = token;
return call_site;
}
public VariableDefinitionCollection ReadVariables (MetadataToken local_var_token)
{
if (!MoveTo (Table.StandAloneSig, local_var_token.RID))
return null;
var reader = ReadSignature (ReadBlobIndex ());
const byte local_sig = 0x7;
if (reader.ReadByte () != local_sig)
throw new NotSupportedException ();
var count = reader.ReadCompressedUInt32 ();
if (count == 0)
return null;
var variables = new VariableDefinitionCollection ((int) count);
for (int i = 0; i < count; i++)
variables.Add (new VariableDefinition (reader.ReadTypeSignature ()));
return variables;
}
public IMetadataTokenProvider LookupToken (MetadataToken token)
{
var rid = token.RID;
if (rid == 0)
return null;
if (metadata_reader != null)
return metadata_reader.LookupToken (token);
IMetadataTokenProvider element;
var position = this.position;
var context = this.context;
switch (token.TokenType) {
case TokenType.TypeDef:
element = GetTypeDefinition (rid);
break;
case TokenType.TypeRef:
element = GetTypeReference (rid);
break;
case TokenType.TypeSpec:
element = GetTypeSpecification (rid);
break;
case TokenType.Field:
element = GetFieldDefinition (rid);
break;
case TokenType.Method:
element = GetMethodDefinition (rid);
break;
case TokenType.MemberRef:
element = GetMemberReference (rid);
break;
case TokenType.MethodSpec:
element = GetMethodSpecification (rid);
break;
default:
return null;
}
this.position = position;
this.context = context;
return element;
}
public FieldDefinition GetFieldDefinition (uint rid)
{
InitializeTypeDefinitions ();
var field = metadata.GetFieldDefinition (rid);
if (field != null)
return field;
return LookupField (rid);
}
FieldDefinition LookupField (uint rid)
{
var type = metadata.GetFieldDeclaringType (rid);
if (type == null)
return null;
Mixin.Read (type.Fields);
return metadata.GetFieldDefinition (rid);
}
public MethodDefinition GetMethodDefinition (uint rid)
{
InitializeTypeDefinitions ();
var method = metadata.GetMethodDefinition (rid);
if (method != null)
return method;
return LookupMethod (rid);
}
MethodDefinition LookupMethod (uint rid)
{
var type = metadata.GetMethodDeclaringType (rid);
if (type == null)
return null;
Mixin.Read (type.Methods);
return metadata.GetMethodDefinition (rid);
}
MethodSpecification GetMethodSpecification (uint rid)
{
if (!MoveTo (Table.MethodSpec, rid))
return null;
var element_method = (MethodReference) LookupToken (
ReadMetadataToken (CodedIndex.MethodDefOrRef));
var signature = ReadBlobIndex ();
var method_spec = ReadMethodSpecSignature (signature, element_method);
method_spec.token = new MetadataToken (TokenType.MethodSpec, rid);
return method_spec;
}
MethodSpecification ReadMethodSpecSignature (uint signature, MethodReference method)
{
var reader = ReadSignature (signature);
const byte methodspec_sig = 0x0a;
var call_conv = reader.ReadByte ();
if (call_conv != methodspec_sig)
throw new NotSupportedException ();
var instance = new GenericInstanceMethod (method);
reader.ReadGenericInstanceSignature (method, instance);
return instance;
}
MemberReference GetMemberReference (uint rid)
{
InitializeMemberReferences ();
var member = metadata.GetMemberReference (rid);
if (member != null)
return member;
member = ReadMemberReference (rid);
if (member != null && !member.ContainsGenericParameter)
metadata.AddMemberReference (member);
return member;
}
MemberReference ReadMemberReference (uint rid)
{
if (!MoveTo (Table.MemberRef, rid))
return null;
var token = ReadMetadataToken (CodedIndex.MemberRefParent);
var name = ReadString ();
var signature = ReadBlobIndex ();
MemberReference member;
switch (token.TokenType) {
case TokenType.TypeDef:
case TokenType.TypeRef:
case TokenType.TypeSpec:
member = ReadTypeMemberReference (token, name, signature);
break;
case TokenType.Method:
member = ReadMethodMemberReference (token, name, signature);
break;
default:
throw new NotSupportedException ();
}
member.token = new MetadataToken (TokenType.MemberRef, rid);
if (module.IsWindowsMetadata ())
WindowsRuntimeProjections.Project (member);
return member;
}
MemberReference ReadTypeMemberReference (MetadataToken type, string name, uint signature)
{
var declaring_type = GetTypeDefOrRef (type);
if (!declaring_type.IsArray)
this.context = declaring_type;
var member = ReadMemberReferenceSignature (signature, declaring_type);
member.Name = name;
return member;
}
MemberReference ReadMemberReferenceSignature (uint signature, TypeReference declaring_type)
{
var reader = ReadSignature (signature);
const byte field_sig = 0x6;
if (reader.buffer [reader.position] == field_sig) {
reader.position++;
var field = new FieldReference ();
field.DeclaringType = declaring_type;
field.FieldType = reader.ReadTypeSignature ();
return field;
} else {
var method = new MethodReference ();
method.DeclaringType = declaring_type;
reader.ReadMethodSignature (method);
return method;
}
}
MemberReference ReadMethodMemberReference (MetadataToken token, string name, uint signature)
{
var method = GetMethodDefinition (token.RID);
this.context = method;
var member = ReadMemberReferenceSignature (signature, method.DeclaringType);
member.Name = name;
return member;
}
void InitializeMemberReferences ()
{
if (metadata.MemberReferences != null)
return;
metadata.MemberReferences = new MemberReference [image.GetTableLength (Table.MemberRef)];
}
public IEnumerable<MemberReference> GetMemberReferences ()
{
InitializeMemberReferences ();
var length = image.GetTableLength (Table.MemberRef);
var type_system = module.TypeSystem;
var context = new MethodDefinition (string.Empty, MethodAttributes.Static, type_system.Void);
context.DeclaringType = new TypeDefinition (string.Empty, string.Empty, TypeAttributes.Public);
var member_references = new MemberReference [length];
for (uint i = 1; i <= length; i++) {
this.context = context;
member_references [i - 1] = GetMemberReference (i);
}
return member_references;
}
void InitializeConstants ()
{
if (metadata.Constants != null)
return;
var length = MoveTo (Table.Constant);
var constants = metadata.Constants = new Dictionary<MetadataToken, Row<ElementType, uint>> (length);
for (uint i = 1; i <= length; i++) {
var type = (ElementType) ReadUInt16 ();
var owner = ReadMetadataToken (CodedIndex.HasConstant);
var signature = ReadBlobIndex ();
constants.Add (owner, new Row<ElementType, uint> (type, signature));
}
}
public TypeReference ReadConstantSignature (MetadataToken token)
{
if (token.TokenType != TokenType.Signature)
throw new NotSupportedException ();
if (token.RID == 0)
return null;
if (!MoveTo (Table.StandAloneSig, token.RID))
return null;
return ReadFieldType (ReadBlobIndex ());
}
public object ReadConstant (IConstantProvider owner)
{
InitializeConstants ();
Row<ElementType, uint> row;
if (!metadata.Constants.TryGetValue (owner.MetadataToken, out row))
return Mixin.NoValue;
metadata.Constants.Remove (owner.MetadataToken);
return ReadConstantValue (row.Col1, row.Col2);
}
object ReadConstantValue (ElementType etype, uint signature)
{
switch (etype) {
case ElementType.Class:
case ElementType.Object:
return null;
case ElementType.String:
return ReadConstantString (signature);
default:
return ReadConstantPrimitive (etype, signature);
}
}
string ReadConstantString (uint signature)
{
byte [] blob;
int index, count;
GetBlobView (signature, out blob, out index, out count);
if (count == 0)
return string.Empty;
if ((count & 1) == 1)
count--;
return Encoding.Unicode.GetString (blob, index, count);
}
object ReadConstantPrimitive (ElementType type, uint signature)
{
var reader = ReadSignature (signature);
return reader.ReadConstantSignature (type);
}
internal void InitializeCustomAttributes ()
{
if (metadata.CustomAttributes != null)
return;
metadata.CustomAttributes = InitializeRanges (
Table.CustomAttribute, () => {
var next = ReadMetadataToken (CodedIndex.HasCustomAttribute);
ReadMetadataToken (CodedIndex.CustomAttributeType);
ReadBlobIndex ();
return next;
});
}
public bool HasCustomAttributes (ICustomAttributeProvider owner)
{
InitializeCustomAttributes ();
Range [] ranges;
if (!metadata.TryGetCustomAttributeRanges (owner, out ranges))
return false;
return RangesSize (ranges) > 0;
}
public Collection<CustomAttribute> ReadCustomAttributes (ICustomAttributeProvider owner)
{
InitializeCustomAttributes ();
Range [] ranges;
if (!metadata.TryGetCustomAttributeRanges (owner, out ranges))
return new Collection<CustomAttribute> ();
var custom_attributes = new Collection<CustomAttribute> (RangesSize (ranges));
for (int i = 0; i < ranges.Length; i++)
ReadCustomAttributeRange (ranges [i], custom_attributes);
metadata.RemoveCustomAttributeRange (owner);
if (module.IsWindowsMetadata ())
foreach (var custom_attribute in custom_attributes)
WindowsRuntimeProjections.Project (owner, custom_attribute);
return custom_attributes;
}
void ReadCustomAttributeRange (Range range, Collection<CustomAttribute> custom_attributes)
{
if (!MoveTo (Table.CustomAttribute, range.Start))
return;
for (var i = 0; i < range.Length; i++) {
ReadMetadataToken (CodedIndex.HasCustomAttribute);
var constructor = (MethodReference) LookupToken (
ReadMetadataToken (CodedIndex.CustomAttributeType));
var signature = ReadBlobIndex ();
custom_attributes.Add (new CustomAttribute (signature, constructor));
}
}
static int RangesSize (Range [] ranges)
{
uint size = 0;
for (int i = 0; i < ranges.Length; i++)
size += ranges [i].Length;
return (int) size;
}
public IEnumerable<CustomAttribute> GetCustomAttributes ()
{
InitializeTypeDefinitions ();
var length = image.TableHeap [Table.CustomAttribute].Length;
var custom_attributes = new Collection<CustomAttribute> ((int) length);
ReadCustomAttributeRange (new Range (1, length), custom_attributes);
return custom_attributes;
}
public byte [] ReadCustomAttributeBlob (uint signature)
{
return ReadBlob (signature);
}
public void ReadCustomAttributeSignature (CustomAttribute attribute)
{
var reader = ReadSignature (attribute.signature);
if (!reader.CanReadMore ())
return;
if (reader.ReadUInt16 () != 0x0001)
throw new InvalidOperationException ();
var constructor = attribute.Constructor;
if (constructor.HasParameters)
reader.ReadCustomAttributeConstructorArguments (attribute, constructor.Parameters);
if (!reader.CanReadMore ())
return;
var named = reader.ReadUInt16 ();
if (named == 0)
return;
reader.ReadCustomAttributeNamedArguments (named, ref attribute.fields, ref attribute.properties);
}
void InitializeMarshalInfos ()
{
if (metadata.FieldMarshals != null)
return;
var length = MoveTo (Table.FieldMarshal);
var marshals = metadata.FieldMarshals = new Dictionary<MetadataToken, uint> (length);
for (int i = 0; i < length; i++) {
var token = ReadMetadataToken (CodedIndex.HasFieldMarshal);
var signature = ReadBlobIndex ();
if (token.RID == 0)
continue;
marshals.Add (token, signature);
}
}
public bool HasMarshalInfo (IMarshalInfoProvider owner)
{
InitializeMarshalInfos ();
return metadata.FieldMarshals.ContainsKey (owner.MetadataToken);
}
public MarshalInfo ReadMarshalInfo (IMarshalInfoProvider owner)
{
InitializeMarshalInfos ();
uint signature;
if (!metadata.FieldMarshals.TryGetValue (owner.MetadataToken, out signature))
return null;
var reader = ReadSignature (signature);
metadata.FieldMarshals.Remove (owner.MetadataToken);
return reader.ReadMarshalInfo ();
}
void InitializeSecurityDeclarations ()
{
if (metadata.SecurityDeclarations != null)
return;
metadata.SecurityDeclarations = InitializeRanges (
Table.DeclSecurity, () => {
ReadUInt16 ();
var next = ReadMetadataToken (CodedIndex.HasDeclSecurity);
ReadBlobIndex ();
return next;
});
}
public bool HasSecurityDeclarations (ISecurityDeclarationProvider owner)
{
InitializeSecurityDeclarations ();
Range [] ranges;
if (!metadata.TryGetSecurityDeclarationRanges (owner, out ranges))
return false;
return RangesSize (ranges) > 0;
}
public Collection<SecurityDeclaration> ReadSecurityDeclarations (ISecurityDeclarationProvider owner)
{
InitializeSecurityDeclarations ();
Range [] ranges;
if (!metadata.TryGetSecurityDeclarationRanges (owner, out ranges))
return new Collection<SecurityDeclaration> ();
var security_declarations = new Collection<SecurityDeclaration> (RangesSize (ranges));
for (int i = 0; i < ranges.Length; i++)
ReadSecurityDeclarationRange (ranges [i], security_declarations);
metadata.RemoveSecurityDeclarationRange (owner);
return security_declarations;
}
void ReadSecurityDeclarationRange (Range range, Collection<SecurityDeclaration> security_declarations)
{
if (!MoveTo (Table.DeclSecurity, range.Start))
return;
for (int i = 0; i < range.Length; i++) {
var action = (SecurityAction) ReadUInt16 ();
ReadMetadataToken (CodedIndex.HasDeclSecurity);
var signature = ReadBlobIndex ();
security_declarations.Add (new SecurityDeclaration (action, signature, module));
}
}
public byte [] ReadSecurityDeclarationBlob (uint signature)
{
return ReadBlob (signature);
}
public void ReadSecurityDeclarationSignature (SecurityDeclaration declaration)
{
var signature = declaration.signature;
var reader = ReadSignature (signature);
if (reader.buffer [reader.position] != '.') {
ReadXmlSecurityDeclaration (signature, declaration);
return;
}
reader.position++;
var count = reader.ReadCompressedUInt32 ();
var attributes = new Collection<SecurityAttribute> ((int) count);
for (int i = 0; i < count; i++)
attributes.Add (reader.ReadSecurityAttribute ());
declaration.security_attributes = attributes;
}
void ReadXmlSecurityDeclaration (uint signature, SecurityDeclaration declaration)
{
var attributes = new Collection<SecurityAttribute> (1);
var attribute = new SecurityAttribute (
module.TypeSystem.LookupType ("System.Security.Permissions", "PermissionSetAttribute"));
attribute.properties = new Collection<CustomAttributeNamedArgument> (1);
attribute.properties.Add (
new CustomAttributeNamedArgument (
"XML",
new CustomAttributeArgument (
module.TypeSystem.String,
ReadUnicodeStringBlob (signature))));
attributes.Add (attribute);
declaration.security_attributes = attributes;
}
public Collection<ExportedType> ReadExportedTypes ()
{
var length = MoveTo (Table.ExportedType);
if (length == 0)
return new Collection<ExportedType> ();
var exported_types = new Collection<ExportedType> (length);
for (int i = 1; i <= length; i++) {
var attributes = (TypeAttributes) ReadUInt32 ();
var identifier = ReadUInt32 ();
var name = ReadString ();
var @namespace = ReadString ();
var implementation = ReadMetadataToken (CodedIndex.Implementation);
ExportedType declaring_type = null;
IMetadataScope scope = null;
switch (implementation.TokenType) {
case TokenType.AssemblyRef:
case TokenType.File:
scope = GetExportedTypeScope (implementation);
break;
case TokenType.ExportedType:
// FIXME: if the table is not properly sorted
declaring_type = exported_types [(int) implementation.RID - 1];
break;
}
var exported_type = new ExportedType (@namespace, name, module, scope) {
Attributes = attributes,
Identifier = (int) identifier,
DeclaringType = declaring_type,
};
exported_type.token = new MetadataToken (TokenType.ExportedType, i);
exported_types.Add (exported_type);
}
return exported_types;
}
IMetadataScope GetExportedTypeScope (MetadataToken token)
{
var position = this.position;
IMetadataScope scope;
switch (token.TokenType) {
case TokenType.AssemblyRef:
InitializeAssemblyReferences ();
scope = metadata.GetAssemblyNameReference (token.RID);
break;
case TokenType.File:
InitializeModuleReferences ();
scope = GetModuleReferenceFromFile (token);
break;
default:
throw new NotSupportedException ();
}
this.position = position;
return scope;
}
ModuleReference GetModuleReferenceFromFile (MetadataToken token)
{
if (!MoveTo (Table.File, token.RID))
return null;
ReadUInt32 ();
var file_name = ReadString ();
var modules = module.ModuleReferences;
ModuleReference reference;
for (int i = 0; i < modules.Count; i++) {
reference = modules [i];
if (reference.Name == file_name)
return reference;
}
reference = new ModuleReference (file_name);
modules.Add (reference);
return reference;
}
void InitializeDocuments ()
{
if (metadata.Documents != null)
return;
int length = MoveTo (Table.Document);
var documents = metadata.Documents = new Document [length];
for (uint i = 1; i <= length; i++) {
var name_index = ReadBlobIndex ();
var hash_algorithm = ReadGuid ();
var hash = ReadBlob ();
var language = ReadGuid ();
var signature = ReadSignature (name_index);
var name = signature.ReadDocumentName ();
documents [i - 1] = new Document (name) {
HashAlgorithmGuid = hash_algorithm,
Hash = hash,
LanguageGuid = language,
token = new MetadataToken (TokenType.Document, i),
};
}
}
public Collection<SequencePoint> ReadSequencePoints (MethodDefinition method)
{
InitializeDocuments ();
if (!MoveTo (Table.MethodDebugInformation, method.MetadataToken.RID))
return new Collection<SequencePoint> (0);
var document_index = ReadTableIndex (Table.Document);
var signature = ReadBlobIndex ();
if (signature == 0)
return new Collection<SequencePoint> (0);
var document = GetDocument (document_index);
var reader = ReadSignature (signature);
return reader.ReadSequencePoints (document);
}
public Document GetDocument (uint rid)
{
var document = metadata.GetDocument (rid);
if (document == null)
return null;
document.custom_infos = GetCustomDebugInformation (document);
return document;
}
void InitializeLocalScopes ()
{
if (metadata.LocalScopes != null)
return;
InitializeMethods ();
int length = MoveTo (Table.LocalScope);
metadata.LocalScopes = new Dictionary<uint, Collection<Row<uint, Range, Range, uint, uint, uint>>> ();
for (uint i = 1; i <= length; i++) {
var method = ReadTableIndex (Table.Method);
var import = ReadTableIndex (Table.ImportScope);
var variables = ReadListRange (i, Table.LocalScope, Table.LocalVariable);
var constants = ReadListRange (i, Table.LocalScope, Table.LocalConstant);
var scope_start = ReadUInt32 ();
var scope_length = ReadUInt32 ();
metadata.SetLocalScopes (method, AddMapping (metadata.LocalScopes, method, new Row<uint, Range, Range, uint, uint, uint> (import, variables, constants, scope_start, scope_length, i)));
}
}
public ScopeDebugInformation ReadScope (MethodDefinition method)
{
InitializeLocalScopes ();
InitializeImportScopes ();
Collection<Row<uint, Range, Range, uint, uint, uint>> records;
if (!metadata.TryGetLocalScopes (method, out records))
return null;
var method_scope = null as ScopeDebugInformation;
for (int i = 0; i < records.Count; i++) {
var scope = ReadLocalScope (records [i]);
if (i == 0) {
method_scope = scope;
continue;
}
if (!AddScope (method_scope.scopes, scope))
method_scope.Scopes.Add (scope);
}
return method_scope;
}
static bool AddScope (Collection<ScopeDebugInformation> scopes, ScopeDebugInformation scope)
{
if (scopes.IsNullOrEmpty ())
return false;
foreach (var sub_scope in scopes) {
if (sub_scope.HasScopes && AddScope (sub_scope.Scopes, scope))
return true;
if (scope.Start.Offset >= sub_scope.Start.Offset && scope.End.Offset <= sub_scope.End.Offset) {
sub_scope.Scopes.Add (scope);
return true;
}
}
return false;
}
ScopeDebugInformation ReadLocalScope (Row<uint, Range, Range, uint, uint, uint> record)
{
var scope = new ScopeDebugInformation
{
start = new InstructionOffset ((int) record.Col4),
end = new InstructionOffset ((int) (record.Col4 + record.Col5)),
token = new MetadataToken (TokenType.LocalScope, record.Col6),
};
if (record.Col1 > 0)
scope.import = metadata.GetImportScope (record.Col1);
if (record.Col2.Length > 0) {
scope.variables = new Collection<VariableDebugInformation> ((int) record.Col2.Length);
for (uint i = 0; i < record.Col2.Length; i++) {
var variable = ReadLocalVariable (record.Col2.Start + i);
if (variable != null)
scope.variables.Add (variable);
}
}
if (record.Col3.Length > 0) {
scope.constants = new Collection<ConstantDebugInformation> ((int) record.Col3.Length);
for (uint i = 0; i < record.Col3.Length; i++) {
var constant = ReadLocalConstant (record.Col3.Start + i);
if (constant != null)
scope.constants.Add (constant);
}
}
return scope;
}
VariableDebugInformation ReadLocalVariable (uint rid)
{
if (!MoveTo (Table.LocalVariable, rid))
return null;
var attributes = (VariableAttributes) ReadUInt16 ();
var index = ReadUInt16 ();
var name = ReadString ();
var variable = new VariableDebugInformation (index, name) { Attributes = attributes, token = new MetadataToken (TokenType.LocalVariable, rid) };
variable.custom_infos = GetCustomDebugInformation (variable);
return variable;
}
ConstantDebugInformation ReadLocalConstant (uint rid)
{
if (!MoveTo (Table.LocalConstant, rid))
return null;
var name = ReadString ();
var signature = ReadSignature (ReadBlobIndex ());
var type = signature.ReadTypeSignature ();
object value;
if (type.etype == ElementType.String) {
if (signature.buffer [signature.position] != 0xff) {
var bytes = signature.ReadBytes ((int) (signature.sig_length - (signature.position - signature.start)));
value = Encoding.Unicode.GetString (bytes, 0, bytes.Length);
} else
value = null;
} else if (type.IsTypeOf ("System", "Decimal")) {
var b = signature.ReadByte ();
value = new decimal (signature.ReadInt32 (), signature.ReadInt32 (), signature.ReadInt32 (), (b & 0x80) != 0, (byte) (b & 0x7f));
} else if (type.IsTypeOf ("System", "DateTime")) {
value = new DateTime (signature.ReadInt64());
} else if (type.etype == ElementType.Object || type.etype == ElementType.None || type.etype == ElementType.Class) {
value = null;
} else
value = signature.ReadConstantSignature (type.etype);
var constant = new ConstantDebugInformation (name, type, value) { token = new MetadataToken (TokenType.LocalConstant, rid) };
constant.custom_infos = GetCustomDebugInformation (constant);
return constant;
}
void InitializeImportScopes ()
{
if (metadata.ImportScopes != null)
return;
var length = MoveTo (Table.ImportScope);
metadata.ImportScopes = new ImportDebugInformation [length];
for (int i = 1; i <= length; i++) {
ReadTableIndex (Table.ImportScope);
var import = new ImportDebugInformation ();
import.token = new MetadataToken (TokenType.ImportScope, i);
var signature = ReadSignature (ReadBlobIndex ());
while (signature.CanReadMore ())
import.Targets.Add (ReadImportTarget (signature));
metadata.ImportScopes [i - 1] = import;
}
MoveTo (Table.ImportScope);
for (int i = 0; i < length; i++) {
var parent = ReadTableIndex (Table.ImportScope);
ReadBlobIndex ();
if (parent != 0)
metadata.ImportScopes [i].Parent = metadata.GetImportScope (parent);
}
}
public string ReadUTF8StringBlob (uint signature)
{
return ReadStringBlob (signature, Encoding.UTF8);
}
string ReadUnicodeStringBlob (uint signature)
{
return ReadStringBlob (signature, Encoding.Unicode);
}
string ReadStringBlob (uint signature, Encoding encoding)
{
byte [] blob;
int index, count;
GetBlobView (signature, out blob, out index, out count);
if (count == 0)
return string.Empty;
return encoding.GetString (blob, index, count);
}
ImportTarget ReadImportTarget (SignatureReader signature)
{
AssemblyNameReference reference = null;
string @namespace = null;
string alias = null;
TypeReference type = null;
var kind = (ImportTargetKind) signature.ReadCompressedUInt32 ();
switch (kind) {
case ImportTargetKind.ImportNamespace:
@namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
break;
case ImportTargetKind.ImportNamespaceInAssembly:
reference = metadata.GetAssemblyNameReference (signature.ReadCompressedUInt32 ());
@namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
break;
case ImportTargetKind.ImportType:
type = signature.ReadTypeToken ();
break;
case ImportTargetKind.ImportXmlNamespaceWithAlias:
alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
@namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
break;
case ImportTargetKind.ImportAlias:
alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
break;
case ImportTargetKind.DefineAssemblyAlias:
alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
reference = metadata.GetAssemblyNameReference (signature.ReadCompressedUInt32 ());
break;
case ImportTargetKind.DefineNamespaceAlias:
alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
@namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
break;
case ImportTargetKind.DefineNamespaceInAssemblyAlias:
alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
reference = metadata.GetAssemblyNameReference (signature.ReadCompressedUInt32 ());
@namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
break;
case ImportTargetKind.DefineTypeAlias:
alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
type = signature.ReadTypeToken ();
break;
}
return new ImportTarget (kind) {
alias = alias,
type = type,
@namespace = @namespace,
reference = reference,
};
}
void InitializeStateMachineMethods ()
{
if (metadata.StateMachineMethods != null)
return;
var length = MoveTo (Table.StateMachineMethod);
metadata.StateMachineMethods = new Dictionary<uint, uint> (length);
for (int i = 0; i < length; i++)
metadata.StateMachineMethods.Add (ReadTableIndex (Table.Method), ReadTableIndex (Table.Method));
}
public MethodDefinition ReadStateMachineKickoffMethod (MethodDefinition method)
{
InitializeStateMachineMethods ();
uint rid;
if (!metadata.TryGetStateMachineKickOffMethod (method, out rid))
return null;
return GetMethodDefinition (rid);
}
void InitializeCustomDebugInformations ()
{
if (metadata.CustomDebugInformations != null)
return;
var length = MoveTo (Table.CustomDebugInformation);
metadata.CustomDebugInformations = new Dictionary<MetadataToken, Row<Guid, uint, uint> []> ();
for (uint i = 1; i <= length; i++) {
var token = ReadMetadataToken (CodedIndex.HasCustomDebugInformation);
var info = new Row<Guid, uint, uint> (ReadGuid (), ReadBlobIndex (), i);
Row<Guid, uint, uint> [] infos;
metadata.CustomDebugInformations.TryGetValue (token, out infos);
metadata.CustomDebugInformations [token] = infos.Add (info);
}
}
public Collection<CustomDebugInformation> GetCustomDebugInformation (ICustomDebugInformationProvider provider)
{
InitializeCustomDebugInformations ();
Row<Guid, uint, uint> [] rows;
if (!metadata.CustomDebugInformations.TryGetValue (provider.MetadataToken, out rows))
return null;
var infos = new Collection<CustomDebugInformation> (rows.Length);
for (int i = 0; i < rows.Length; i++) {
if (rows [i].Col1 == StateMachineScopeDebugInformation.KindIdentifier) {
var signature = ReadSignature (rows [i].Col2);
var scopes = new Collection<StateMachineScope> ();
while (signature.CanReadMore ()) {
var start = signature.ReadInt32 ();
var end = start + signature.ReadInt32 ();
scopes.Add (new StateMachineScope (start, end));
}
var state_machine = new StateMachineScopeDebugInformation ();
state_machine.scopes = scopes;
infos.Add (state_machine);
} else if (rows [i].Col1 == AsyncMethodBodyDebugInformation.KindIdentifier) {
var signature = ReadSignature (rows [i].Col2);
var catch_offset = signature.ReadInt32 () - 1;
var yields = new Collection<InstructionOffset> ();
var resumes = new Collection<InstructionOffset> ();
var resume_methods = new Collection<MethodDefinition> ();
while (signature.CanReadMore ()) {
yields.Add (new InstructionOffset (signature.ReadInt32 ()));
resumes.Add (new InstructionOffset (signature.ReadInt32 ()));
resume_methods.Add (GetMethodDefinition (signature.ReadCompressedUInt32 ()));
}
var async_body = new AsyncMethodBodyDebugInformation (catch_offset);
async_body.yields = yields;
async_body.resumes = resumes;
async_body.resume_methods = resume_methods;
infos.Add (async_body);
} else if (rows [i].Col1 == EmbeddedSourceDebugInformation.KindIdentifier) {
var signature = ReadSignature (rows [i].Col2);
var format = signature.ReadInt32 ();
var length = signature.sig_length - 4;
var info = null as CustomDebugInformation;
if (format == 0) {
info = new EmbeddedSourceDebugInformation (signature.ReadBytes ((int) length), compress: false);
} else if (format > 0) {
var compressed_stream = new MemoryStream (signature.ReadBytes ((int) length));
var decompressed_document = new byte [format]; // if positive, format is the decompressed length of the document
var decompressed_stream = new MemoryStream (decompressed_document);
using (var deflate_stream = new DeflateStream (compressed_stream, CompressionMode.Decompress, leaveOpen: true))
deflate_stream.CopyTo (decompressed_stream);
info = new EmbeddedSourceDebugInformation (decompressed_document, compress: true);
} else if (format < 0) {
info = new BinaryCustomDebugInformation (rows [i].Col1, ReadBlob (rows [i].Col2));
}
infos.Add (info);
} else if (rows [i].Col1 == SourceLinkDebugInformation.KindIdentifier) {
infos.Add (new SourceLinkDebugInformation (Encoding.UTF8.GetString (ReadBlob (rows [i].Col2))));
} else {
infos.Add (new BinaryCustomDebugInformation (rows [i].Col1, ReadBlob (rows [i].Col2)));
}
infos [i].token = new MetadataToken (TokenType.CustomDebugInformation, rows [i].Col3);
}
return infos;
}
}
sealed class SignatureReader : ByteBuffer {
readonly MetadataReader reader;
readonly internal uint start, sig_length;
TypeSystem TypeSystem {
get { return reader.module.TypeSystem; }
}
public SignatureReader (uint blob, MetadataReader reader)
: base (reader.image.BlobHeap.data)
{
this.reader = reader;
this.position = (int) blob;
this.sig_length = ReadCompressedUInt32();
this.start = (uint) this.position;
}
MetadataToken ReadTypeTokenSignature ()
{
return CodedIndex.TypeDefOrRef.GetMetadataToken (ReadCompressedUInt32 ());
}
GenericParameter GetGenericParameter (GenericParameterType type, uint var)
{
var context = reader.context;
int index = (int) var;
if (context == null)
return GetUnboundGenericParameter (type, index);
IGenericParameterProvider provider;
switch (type) {
case GenericParameterType.Type:
provider = context.Type;
break;
case GenericParameterType.Method:
provider = context.Method;
break;
default:
throw new NotSupportedException ();
}
if (!context.IsDefinition)
CheckGenericContext (provider, index);
if (index >= provider.GenericParameters.Count)
return GetUnboundGenericParameter (type, index);
return provider.GenericParameters [index];
}
GenericParameter GetUnboundGenericParameter (GenericParameterType type, int index)
{
return new GenericParameter (index, type, reader.module);
}
static void CheckGenericContext (IGenericParameterProvider owner, int index)
{
var owner_parameters = owner.GenericParameters;
for (int i = owner_parameters.Count; i <= index; i++)
owner_parameters.Add (new GenericParameter (owner));
}
public void ReadGenericInstanceSignature (IGenericParameterProvider provider, IGenericInstance instance)
{
var arity = ReadCompressedUInt32 ();
if (!provider.IsDefinition)
CheckGenericContext (provider, (int) arity - 1);
var instance_arguments = instance.GenericArguments;
for (int i = 0; i < arity; i++)
instance_arguments.Add (ReadTypeSignature ());
}
ArrayType ReadArrayTypeSignature ()
{
var array = new ArrayType (ReadTypeSignature ());
var rank = ReadCompressedUInt32 ();
var sizes = new uint [ReadCompressedUInt32 ()];
for (int i = 0; i < sizes.Length; i++)
sizes [i] = ReadCompressedUInt32 ();
var low_bounds = new int [ReadCompressedUInt32 ()];
for (int i = 0; i < low_bounds.Length; i++)
low_bounds [i] = ReadCompressedInt32 ();
array.Dimensions.Clear ();
for (int i = 0; i < rank; i++) {
int? lower = null, upper = null;
if (i < low_bounds.Length)
lower = low_bounds [i];
if (i < sizes.Length)
upper = lower + (int) sizes [i] - 1;
array.Dimensions.Add (new ArrayDimension (lower, upper));
}
return array;
}
TypeReference GetTypeDefOrRef (MetadataToken token)
{
return reader.GetTypeDefOrRef (token);
}
public TypeReference ReadTypeSignature ()
{
return ReadTypeSignature ((ElementType) ReadByte ());
}
public TypeReference ReadTypeToken ()
{
return GetTypeDefOrRef (ReadTypeTokenSignature ());
}
TypeReference ReadTypeSignature (ElementType etype)
{
switch (etype) {
case ElementType.ValueType: {
var value_type = GetTypeDefOrRef (ReadTypeTokenSignature ());
value_type.KnownValueType ();
return value_type;
}
case ElementType.Class:
return GetTypeDefOrRef (ReadTypeTokenSignature ());
case ElementType.Ptr:
return new PointerType (ReadTypeSignature ());
case ElementType.FnPtr: {
var fptr = new FunctionPointerType ();
ReadMethodSignature (fptr);
return fptr;
}
case ElementType.ByRef:
return new ByReferenceType (ReadTypeSignature ());
case ElementType.Pinned:
return new PinnedType (ReadTypeSignature ());
case ElementType.SzArray:
return new ArrayType (ReadTypeSignature ());
case ElementType.Array:
return ReadArrayTypeSignature ();
case ElementType.CModOpt:
return new OptionalModifierType (
GetTypeDefOrRef (ReadTypeTokenSignature ()), ReadTypeSignature ());
case ElementType.CModReqD:
return new RequiredModifierType (
GetTypeDefOrRef (ReadTypeTokenSignature ()), ReadTypeSignature ());
case ElementType.Sentinel:
return new SentinelType (ReadTypeSignature ());
case ElementType.Var:
return GetGenericParameter (GenericParameterType.Type, ReadCompressedUInt32 ());
case ElementType.MVar:
return GetGenericParameter (GenericParameterType.Method, ReadCompressedUInt32 ());
case ElementType.GenericInst: {
var is_value_type = ReadByte () == (byte) ElementType.ValueType;
var element_type = GetTypeDefOrRef (ReadTypeTokenSignature ());
var generic_instance = new GenericInstanceType (element_type);
ReadGenericInstanceSignature (element_type, generic_instance);
if (is_value_type) {
generic_instance.KnownValueType ();
element_type.GetElementType ().KnownValueType ();
}
return generic_instance;
}
case ElementType.Object: return TypeSystem.Object;
case ElementType.Void: return TypeSystem.Void;
case ElementType.TypedByRef: return TypeSystem.TypedReference;
case ElementType.I: return TypeSystem.IntPtr;
case ElementType.U: return TypeSystem.UIntPtr;
default: return GetPrimitiveType (etype);
}
}
public void ReadMethodSignature (IMethodSignature method)
{
var calling_convention = ReadByte ();
const byte has_this = 0x20;
const byte explicit_this = 0x40;
if ((calling_convention & has_this) != 0) {
method.HasThis = true;
calling_convention = (byte) (calling_convention & ~has_this);
}
if ((calling_convention & explicit_this) != 0) {
method.ExplicitThis = true;
calling_convention = (byte) (calling_convention & ~explicit_this);
}
method.CallingConvention = (MethodCallingConvention) calling_convention;
var generic_context = method as MethodReference;
if (generic_context != null && !generic_context.DeclaringType.IsArray)
reader.context = generic_context;
if ((calling_convention & 0x10) != 0) {
var arity = ReadCompressedUInt32 ();
if (generic_context != null && !generic_context.IsDefinition)
CheckGenericContext (generic_context, (int) arity -1 );
}
var param_count = ReadCompressedUInt32 ();
method.MethodReturnType.ReturnType = ReadTypeSignature ();
if (param_count == 0)
return;
Collection<ParameterDefinition> parameters;
var method_ref = method as MethodReference;
if (method_ref != null)
parameters = method_ref.parameters = new ParameterDefinitionCollection (method, (int) param_count);
else
parameters = method.Parameters;
for (int i = 0; i < param_count; i++)
parameters.Add (new ParameterDefinition (ReadTypeSignature ()));
}
public object ReadConstantSignature (ElementType type)
{
return ReadPrimitiveValue (type);
}
public void ReadCustomAttributeConstructorArguments (CustomAttribute attribute, Collection<ParameterDefinition> parameters)
{
var count = parameters.Count;
if (count == 0)
return;
attribute.arguments = new Collection<CustomAttributeArgument> (count);
for (int i = 0; i < count; i++)
attribute.arguments.Add (
ReadCustomAttributeFixedArgument (parameters [i].ParameterType));
}
CustomAttributeArgument ReadCustomAttributeFixedArgument (TypeReference type)
{
if (type.IsArray)
return ReadCustomAttributeFixedArrayArgument ((ArrayType) type);
return ReadCustomAttributeElement (type);
}
public void ReadCustomAttributeNamedArguments (ushort count, ref Collection<CustomAttributeNamedArgument> fields, ref Collection<CustomAttributeNamedArgument> properties)
{
for (int i = 0; i < count; i++) {
if (!CanReadMore ())
return;
ReadCustomAttributeNamedArgument (ref fields, ref properties);
}
}
void ReadCustomAttributeNamedArgument (ref Collection<CustomAttributeNamedArgument> fields, ref Collection<CustomAttributeNamedArgument> properties)
{
var kind = ReadByte ();
var type = ReadCustomAttributeFieldOrPropType ();
var name = ReadUTF8String ();
Collection<CustomAttributeNamedArgument> container;
switch (kind) {
case 0x53:
container = GetCustomAttributeNamedArgumentCollection (ref fields);
break;
case 0x54:
container = GetCustomAttributeNamedArgumentCollection (ref properties);
break;
default:
throw new NotSupportedException ();
}
container.Add (new CustomAttributeNamedArgument (name, ReadCustomAttributeFixedArgument (type)));
}
static Collection<CustomAttributeNamedArgument> GetCustomAttributeNamedArgumentCollection (ref Collection<CustomAttributeNamedArgument> collection)
{
if (collection != null)
return collection;
return collection = new Collection<CustomAttributeNamedArgument> ();
}
CustomAttributeArgument ReadCustomAttributeFixedArrayArgument (ArrayType type)
{
var length = ReadUInt32 ();
if (length == 0xffffffff)
return new CustomAttributeArgument (type, null);
if (length == 0)
return new CustomAttributeArgument (type, Empty<CustomAttributeArgument>.Array);
var arguments = new CustomAttributeArgument [length];
var element_type = type.ElementType;
for (int i = 0; i < length; i++)
arguments [i] = ReadCustomAttributeElement (element_type);
return new CustomAttributeArgument (type, arguments);
}
CustomAttributeArgument ReadCustomAttributeElement (TypeReference type)
{
if (type.IsArray)
return ReadCustomAttributeFixedArrayArgument ((ArrayType) type);
return new CustomAttributeArgument (
type,
type.etype == ElementType.Object
? ReadCustomAttributeElement (ReadCustomAttributeFieldOrPropType ())
: ReadCustomAttributeElementValue (type));
}
object ReadCustomAttributeElementValue (TypeReference type)
{
var etype = type.etype;
switch (etype) {
case ElementType.String:
return ReadUTF8String ();
case ElementType.None:
if (type.IsTypeOf ("System", "Type"))
return ReadTypeReference ();
return ReadCustomAttributeEnum (type);
default:
return ReadPrimitiveValue (etype);
}
}
object ReadPrimitiveValue (ElementType type)
{
switch (type) {
case ElementType.Boolean:
return ReadByte () == 1;
case ElementType.I1:
return (sbyte) ReadByte ();
case ElementType.U1:
return ReadByte ();
case ElementType.Char:
return (char) ReadUInt16 ();
case ElementType.I2:
return ReadInt16 ();
case ElementType.U2:
return ReadUInt16 ();
case ElementType.I4:
return ReadInt32 ();
case ElementType.U4:
return ReadUInt32 ();
case ElementType.I8:
return ReadInt64 ();
case ElementType.U8:
return ReadUInt64 ();
case ElementType.R4:
return ReadSingle ();
case ElementType.R8:
return ReadDouble ();
default:
throw new NotImplementedException (type.ToString ());
}
}
TypeReference GetPrimitiveType (ElementType etype)
{
switch (etype) {
case ElementType.Boolean:
return TypeSystem.Boolean;
case ElementType.Char:
return TypeSystem.Char;
case ElementType.I1:
return TypeSystem.SByte;
case ElementType.U1:
return TypeSystem.Byte;
case ElementType.I2:
return TypeSystem.Int16;
case ElementType.U2:
return TypeSystem.UInt16;
case ElementType.I4:
return TypeSystem.Int32;
case ElementType.U4:
return TypeSystem.UInt32;
case ElementType.I8:
return TypeSystem.Int64;
case ElementType.U8:
return TypeSystem.UInt64;
case ElementType.R4:
return TypeSystem.Single;
case ElementType.R8:
return TypeSystem.Double;
case ElementType.String:
return TypeSystem.String;
default:
throw new NotImplementedException (etype.ToString ());
}
}
TypeReference ReadCustomAttributeFieldOrPropType ()
{
var etype = (ElementType) ReadByte ();
switch (etype) {
case ElementType.Boxed:
return TypeSystem.Object;
case ElementType.SzArray:
return new ArrayType (ReadCustomAttributeFieldOrPropType ());
case ElementType.Enum:
return ReadTypeReference ();
case ElementType.Type:
return TypeSystem.LookupType ("System", "Type");
default:
return GetPrimitiveType (etype);
}
}
public TypeReference ReadTypeReference ()
{
return TypeParser.ParseType (reader.module, ReadUTF8String ());
}
object ReadCustomAttributeEnum (TypeReference enum_type)
{
var type = enum_type.CheckedResolve ();
if (!type.IsEnum)
throw new ArgumentException ();
return ReadCustomAttributeElementValue (type.GetEnumUnderlyingType ());
}
public SecurityAttribute ReadSecurityAttribute ()
{
var attribute = new SecurityAttribute (ReadTypeReference ());
ReadCompressedUInt32 ();
ReadCustomAttributeNamedArguments (
(ushort) ReadCompressedUInt32 (),
ref attribute.fields,
ref attribute.properties);
return attribute;
}
public MarshalInfo ReadMarshalInfo ()
{
var native = ReadNativeType ();
switch (native) {
case NativeType.Array: {
var array = new ArrayMarshalInfo ();
if (CanReadMore ())
array.element_type = ReadNativeType ();
if (CanReadMore ())
array.size_parameter_index = (int) ReadCompressedUInt32 ();
if (CanReadMore ())
array.size = (int) ReadCompressedUInt32 ();
if (CanReadMore ())
array.size_parameter_multiplier = (int) ReadCompressedUInt32 ();
return array;
}
case NativeType.SafeArray: {
var array = new SafeArrayMarshalInfo ();
if (CanReadMore ())
array.element_type = ReadVariantType ();
return array;
}
case NativeType.FixedArray: {
var array = new FixedArrayMarshalInfo ();
if (CanReadMore ())
array.size = (int) ReadCompressedUInt32 ();
if (CanReadMore ())
array.element_type = ReadNativeType ();
return array;
}
case NativeType.FixedSysString: {
var sys_string = new FixedSysStringMarshalInfo ();
if (CanReadMore ())
sys_string.size = (int) ReadCompressedUInt32 ();
return sys_string;
}
case NativeType.CustomMarshaler: {
var marshaler = new CustomMarshalInfo ();
var guid_value = ReadUTF8String ();
marshaler.guid = !string.IsNullOrEmpty (guid_value) ? new Guid (guid_value) : Guid.Empty;
marshaler.unmanaged_type = ReadUTF8String ();
marshaler.managed_type = ReadTypeReference ();
marshaler.cookie = ReadUTF8String ();
return marshaler;
}
default:
return new MarshalInfo (native);
}
}
NativeType ReadNativeType ()
{
return (NativeType) ReadByte ();
}
VariantType ReadVariantType ()
{
return (VariantType) ReadByte ();
}
string ReadUTF8String ()
{
if (buffer [position] == 0xff) {
position++;
return null;
}
var length = (int) ReadCompressedUInt32 ();
if (length == 0)
return string.Empty;
if (position + length >= buffer.Length)
return string.Empty;
var @string = Encoding.UTF8.GetString (buffer, position, length);
position += length;
return @string;
}
public string ReadDocumentName ()
{
var separator = (char) buffer [position];
position++;
var builder = new StringBuilder ();
for (int i = 0; CanReadMore (); i++) {
if (i > 0 && separator != 0)
builder.Append (separator);
uint part = ReadCompressedUInt32 ();
if (part != 0)
builder.Append (reader.ReadUTF8StringBlob (part));
}
return builder.ToString ();
}
public Collection<SequencePoint> ReadSequencePoints (Document document)
{
var sequence_points = new Collection<SequencePoint> ();
ReadCompressedUInt32 (); // local_sig_token
if (document == null)
document = reader.GetDocument (ReadCompressedUInt32 ());
var offset = 0;
var start_line = 0;
var start_column = 0;
var first_non_hidden = true;
for (var i = 0; CanReadMore (); i++) {
var delta_il = (int) ReadCompressedUInt32 ();
if (i > 0 && delta_il == 0) {
document = reader.GetDocument (ReadCompressedUInt32 ());
continue;
}
offset += delta_il;
var delta_lines = (int) ReadCompressedUInt32 ();
var delta_columns = delta_lines == 0
? (int) ReadCompressedUInt32 ()
: ReadCompressedInt32 ();
if (delta_lines == 0 && delta_columns == 0) {
sequence_points.Add (new SequencePoint (offset, document) {
StartLine = 0xfeefee,
EndLine = 0xfeefee,
StartColumn = 0,
EndColumn = 0,
});
continue;
}
if (first_non_hidden) {
start_line = (int) ReadCompressedUInt32 ();
start_column = (int) ReadCompressedUInt32 ();
} else {
start_line += ReadCompressedInt32 ();
start_column += ReadCompressedInt32 ();
}
sequence_points.Add (new SequencePoint (offset, document) {
StartLine = start_line,
StartColumn = start_column,
EndLine = start_line + delta_lines,
EndColumn = start_column + delta_columns,
});
first_non_hidden = false;
}
return sequence_points;
}
public bool CanReadMore ()
{
return position - start < sig_length;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Text;
using Mono;
using Mono.Collections.Generic;
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
using Mono.Cecil.PE;
using RVA = System.UInt32;
using RID = System.UInt32;
using CodedRID = System.UInt32;
using StringIndex = System.UInt32;
using BlobIndex = System.UInt32;
using GuidIndex = System.UInt32;
namespace Mono.Cecil {
#if !READ_ONLY
using ModuleRow = Row<StringIndex, GuidIndex>;
using TypeRefRow = Row<CodedRID, StringIndex, StringIndex>;
using TypeDefRow = Row<TypeAttributes, StringIndex, StringIndex, CodedRID, RID, RID>;
using FieldRow = Row<FieldAttributes, StringIndex, BlobIndex>;
using MethodRow = Row<RVA, MethodImplAttributes, MethodAttributes, StringIndex, BlobIndex, RID>;
using ParamRow = Row<ParameterAttributes, ushort, StringIndex>;
using InterfaceImplRow = Row<uint, CodedRID>;
using MemberRefRow = Row<CodedRID, StringIndex, BlobIndex>;
using ConstantRow = Row<ElementType, CodedRID, BlobIndex>;
using CustomAttributeRow = Row<CodedRID, CodedRID, BlobIndex>;
using FieldMarshalRow = Row<CodedRID, BlobIndex>;
using DeclSecurityRow = Row<SecurityAction, CodedRID, BlobIndex>;
using ClassLayoutRow = Row<ushort, uint, RID>;
using FieldLayoutRow = Row<uint, RID>;
using EventMapRow = Row<RID, RID>;
using EventRow = Row<EventAttributes, StringIndex, CodedRID>;
using PropertyMapRow = Row<RID, RID>;
using PropertyRow = Row<PropertyAttributes, StringIndex, BlobIndex>;
using MethodSemanticsRow = Row<MethodSemanticsAttributes, RID, CodedRID>;
using MethodImplRow = Row<RID, CodedRID, CodedRID>;
using ImplMapRow = Row<PInvokeAttributes, CodedRID, StringIndex, RID>;
using FieldRVARow = Row<RVA, RID>;
using AssemblyRow = Row<AssemblyHashAlgorithm, ushort, ushort, ushort, ushort, AssemblyAttributes, uint, uint, uint>;
using AssemblyRefRow = Row<ushort, ushort, ushort, ushort, AssemblyAttributes, uint, uint, uint, uint>;
using FileRow = Row<FileAttributes, StringIndex, BlobIndex>;
using ExportedTypeRow = Row<TypeAttributes, uint, StringIndex, StringIndex, CodedRID>;
using ManifestResourceRow = Row<uint, ManifestResourceAttributes, StringIndex, CodedRID>;
using NestedClassRow = Row<RID, RID>;
using GenericParamRow = Row<ushort, GenericParameterAttributes, CodedRID, StringIndex>;
using MethodSpecRow = Row<CodedRID, BlobIndex>;
using GenericParamConstraintRow = Row<RID, CodedRID>;
using DocumentRow = Row<BlobIndex, GuidIndex, BlobIndex, GuidIndex>;
using MethodDebugInformationRow = Row<RID, BlobIndex>;
using LocalScopeRow = Row<RID, RID, RID, RID, uint, uint>;
using LocalVariableRow = Row<VariableAttributes, ushort, StringIndex>;
using LocalConstantRow = Row<StringIndex, BlobIndex>;
using ImportScopeRow = Row<RID, BlobIndex>;
using StateMachineMethodRow = Row<RID, RID>;
using CustomDebugInformationRow = Row<CodedRID, GuidIndex, BlobIndex>;
static class ModuleWriter {
public static void WriteModule (ModuleDefinition module, Disposable<Stream> stream, WriterParameters parameters)
{
using (stream)
Write (module, stream, parameters);
}
static void Write (ModuleDefinition module, Disposable<Stream> stream, WriterParameters parameters)
{
if ((module.Attributes & ModuleAttributes.ILOnly) == 0)
throw new NotSupportedException ("Writing mixed-mode assemblies is not supported");
if (module.HasImage && module.ReadingMode == ReadingMode.Deferred) {
var immediate_reader = new ImmediateModuleReader (module.Image);
immediate_reader.ReadModule (module, resolve_attributes: false);
immediate_reader.ReadSymbols (module);
}
module.MetadataSystem.Clear ();
if (module.symbol_reader != null)
module.symbol_reader.Dispose ();
var name = module.assembly != null ? module.assembly.Name : null;
var fq_name = stream.value.GetFileName ();
var timestamp = parameters.Timestamp ?? module.timestamp;
var symbol_writer_provider = parameters.SymbolWriterProvider;
if (symbol_writer_provider == null && parameters.WriteSymbols)
symbol_writer_provider = new DefaultSymbolWriterProvider ();
#if !NET_CORE
if (parameters.StrongNameKeyPair != null && name != null) {
name.PublicKey = parameters.StrongNameKeyPair.PublicKey;
module.Attributes |= ModuleAttributes.StrongNameSigned;
}
#endif
using (var symbol_writer = GetSymbolWriter (module, fq_name, symbol_writer_provider, parameters)) {
var metadata = new MetadataBuilder (module, fq_name, timestamp, symbol_writer_provider, symbol_writer);
BuildMetadata (module, metadata);
var writer = ImageWriter.CreateWriter (module, metadata, stream);
stream.value.SetLength (0);
writer.WriteImage ();
#if !NET_CORE
if (parameters.StrongNameKeyPair != null)
CryptoService.StrongName (stream.value, writer, parameters.StrongNameKeyPair);
#endif
}
}
static void BuildMetadata (ModuleDefinition module, MetadataBuilder metadata)
{
if (!module.HasImage) {
metadata.BuildMetadata ();
return;
}
module.Read (metadata, (builder, _) => {
builder.BuildMetadata ();
return builder;
});
}
static ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fq_name, ISymbolWriterProvider symbol_writer_provider, WriterParameters parameters)
{
if (symbol_writer_provider == null)
return null;
if (parameters.SymbolStream != null)
return symbol_writer_provider.GetSymbolWriter (module, parameters.SymbolStream);
return symbol_writer_provider.GetSymbolWriter (module, fq_name);
}
}
abstract class MetadataTable {
public abstract int Length { get; }
public bool IsLarge {
get { return Length > ushort.MaxValue; }
}
public abstract void Write (TableHeapBuffer buffer);
public abstract void Sort ();
}
abstract class OneRowTable<TRow> : MetadataTable where TRow : struct {
internal TRow row;
public sealed override int Length {
get { return 1; }
}
public sealed override void Sort ()
{
}
}
abstract class MetadataTable<TRow> : MetadataTable where TRow : struct {
internal TRow [] rows = new TRow [2];
internal int length;
public sealed override int Length {
get { return length; }
}
public int AddRow (TRow row)
{
if (rows.Length == length)
Grow ();
rows [length++] = row;
return length;
}
void Grow ()
{
var rows = new TRow [this.rows.Length * 2];
Array.Copy (this.rows, rows, this.rows.Length);
this.rows = rows;
}
public override void Sort ()
{
}
}
abstract class SortedTable<TRow> : MetadataTable<TRow>, IComparer<TRow> where TRow : struct {
public sealed override void Sort ()
{
Array.Sort (rows, 0, length, this);
}
protected int Compare (uint x, uint y)
{
return x == y ? 0 : x > y ? 1 : -1;
}
public abstract int Compare (TRow x, TRow y);
}
sealed class ModuleTable : OneRowTable<ModuleRow> {
public override void Write (TableHeapBuffer buffer)
{
buffer.WriteUInt16 (0); // Generation
buffer.WriteString (row.Col1); // Name
buffer.WriteGuid (row.Col2); // Mvid
buffer.WriteUInt16 (0); // EncId
buffer.WriteUInt16 (0); // EncBaseId
}
}
sealed class TypeRefTable : MetadataTable<TypeRefRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteCodedRID (
rows [i].Col1, CodedIndex.ResolutionScope); // Scope
buffer.WriteString (rows [i].Col2); // Name
buffer.WriteString (rows [i].Col3); // Namespace
}
}
}
sealed class TypeDefTable : MetadataTable<TypeDefRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt32 ((uint) rows [i].Col1); // Attributes
buffer.WriteString (rows [i].Col2); // Name
buffer.WriteString (rows [i].Col3); // Namespace
buffer.WriteCodedRID (
rows [i].Col4, CodedIndex.TypeDefOrRef); // Extends
buffer.WriteRID (rows [i].Col5, Table.Field); // FieldList
buffer.WriteRID (rows [i].Col6, Table.Method); // MethodList
}
}
}
sealed class FieldTable : MetadataTable<FieldRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes
buffer.WriteString (rows [i].Col2); // Name
buffer.WriteBlob (rows [i].Col3); // Signature
}
}
}
sealed class MethodTable : MetadataTable<MethodRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt32 (rows [i].Col1); // RVA
buffer.WriteUInt16 ((ushort) rows [i].Col2); // ImplFlags
buffer.WriteUInt16 ((ushort) rows [i].Col3); // Flags
buffer.WriteString (rows [i].Col4); // Name
buffer.WriteBlob (rows [i].Col5); // Signature
buffer.WriteRID (rows [i].Col6, Table.Param); // ParamList
}
}
}
sealed class ParamTable : MetadataTable<ParamRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes
buffer.WriteUInt16 (rows [i].Col2); // Sequence
buffer.WriteString (rows [i].Col3); // Name
}
}
}
sealed class InterfaceImplTable : MetadataTable<InterfaceImplRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Interface
}
}
/*public override int Compare (InterfaceImplRow x, InterfaceImplRow y)
{
return (int) (x.Col1 == y.Col1 ? y.Col2 - x.Col2 : x.Col1 - y.Col1);
}*/
}
sealed class MemberRefTable : MetadataTable<MemberRefRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MemberRefParent);
buffer.WriteString (rows [i].Col2);
buffer.WriteBlob (rows [i].Col3);
}
}
}
sealed class ConstantTable : SortedTable<ConstantRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt16 ((ushort) rows [i].Col1);
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasConstant);
buffer.WriteBlob (rows [i].Col3);
}
}
public override int Compare (ConstantRow x, ConstantRow y)
{
return Compare (x.Col2, y.Col2);
}
}
sealed class CustomAttributeTable : SortedTable<CustomAttributeRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasCustomAttribute); // Parent
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.CustomAttributeType); // Type
buffer.WriteBlob (rows [i].Col3);
}
}
public override int Compare (CustomAttributeRow x, CustomAttributeRow y)
{
return Compare (x.Col1, y.Col1);
}
}
sealed class FieldMarshalTable : SortedTable<FieldMarshalRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasFieldMarshal);
buffer.WriteBlob (rows [i].Col2);
}
}
public override int Compare (FieldMarshalRow x, FieldMarshalRow y)
{
return Compare (x.Col1, y.Col1);
}
}
sealed class DeclSecurityTable : SortedTable<DeclSecurityRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt16 ((ushort) rows [i].Col1);
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasDeclSecurity);
buffer.WriteBlob (rows [i].Col3);
}
}
public override int Compare (DeclSecurityRow x, DeclSecurityRow y)
{
return Compare (x.Col2, y.Col2);
}
}
sealed class ClassLayoutTable : SortedTable<ClassLayoutRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt16 (rows [i].Col1); // PackingSize
buffer.WriteUInt32 (rows [i].Col2); // ClassSize
buffer.WriteRID (rows [i].Col3, Table.TypeDef); // Parent
}
}
public override int Compare (ClassLayoutRow x, ClassLayoutRow y)
{
return Compare (x.Col3, y.Col3);
}
}
sealed class FieldLayoutTable : SortedTable<FieldLayoutRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt32 (rows [i].Col1); // Offset
buffer.WriteRID (rows [i].Col2, Table.Field); // Parent
}
}
public override int Compare (FieldLayoutRow x, FieldLayoutRow y)
{
return Compare (x.Col2, y.Col2);
}
}
sealed class StandAloneSigTable : MetadataTable<uint> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++)
buffer.WriteBlob (rows [i]);
}
}
sealed class EventMapTable : MetadataTable<EventMapRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent
buffer.WriteRID (rows [i].Col2, Table.Event); // EventList
}
}
}
sealed class EventTable : MetadataTable<EventRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
buffer.WriteString (rows [i].Col2); // Name
buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeDefOrRef); // EventType
}
}
}
sealed class PropertyMapTable : MetadataTable<PropertyMapRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent
buffer.WriteRID (rows [i].Col2, Table.Property); // PropertyList
}
}
}
sealed class PropertyTable : MetadataTable<PropertyRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
buffer.WriteString (rows [i].Col2); // Name
buffer.WriteBlob (rows [i].Col3); // Type
}
}
}
sealed class MethodSemanticsTable : SortedTable<MethodSemanticsRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
buffer.WriteRID (rows [i].Col2, Table.Method); // Method
buffer.WriteCodedRID (rows [i].Col3, CodedIndex.HasSemantics); // Association
}
}
public override int Compare (MethodSemanticsRow x, MethodSemanticsRow y)
{
return Compare (x.Col3, y.Col3);
}
}
sealed class MethodImplTable : MetadataTable<MethodImplRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MethodDefOrRef); // MethodBody
buffer.WriteCodedRID (rows [i].Col3, CodedIndex.MethodDefOrRef); // MethodDeclaration
}
}
}
sealed class ModuleRefTable : MetadataTable<uint> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++)
buffer.WriteString (rows [i]); // Name
}
}
sealed class TypeSpecTable : MetadataTable<uint> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++)
buffer.WriteBlob (rows [i]); // Signature
}
}
sealed class ImplMapTable : SortedTable<ImplMapRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MemberForwarded); // MemberForwarded
buffer.WriteString (rows [i].Col3); // ImportName
buffer.WriteRID (rows [i].Col4, Table.ModuleRef); // ImportScope
}
}
public override int Compare (ImplMapRow x, ImplMapRow y)
{
return Compare (x.Col2, y.Col2);
}
}
sealed class FieldRVATable : SortedTable<FieldRVARow> {
internal int position;
public override void Write (TableHeapBuffer buffer)
{
position = buffer.position;
for (int i = 0; i < length; i++) {
buffer.WriteUInt32 (rows [i].Col1); // RVA
buffer.WriteRID (rows [i].Col2, Table.Field); // Field
}
}
public override int Compare (FieldRVARow x, FieldRVARow y)
{
return Compare (x.Col2, y.Col2);
}
}
sealed class AssemblyTable : OneRowTable<AssemblyRow> {
public override void Write (TableHeapBuffer buffer)
{
buffer.WriteUInt32 ((uint) row.Col1); // AssemblyHashAlgorithm
buffer.WriteUInt16 (row.Col2); // MajorVersion
buffer.WriteUInt16 (row.Col3); // MinorVersion
buffer.WriteUInt16 (row.Col4); // Build
buffer.WriteUInt16 (row.Col5); // Revision
buffer.WriteUInt32 ((uint) row.Col6); // Flags
buffer.WriteBlob (row.Col7); // PublicKey
buffer.WriteString (row.Col8); // Name
buffer.WriteString (row.Col9); // Culture
}
}
sealed class AssemblyRefTable : MetadataTable<AssemblyRefRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt16 (rows [i].Col1); // MajorVersion
buffer.WriteUInt16 (rows [i].Col2); // MinorVersion
buffer.WriteUInt16 (rows [i].Col3); // Build
buffer.WriteUInt16 (rows [i].Col4); // Revision
buffer.WriteUInt32 ((uint) rows [i].Col5); // Flags
buffer.WriteBlob (rows [i].Col6); // PublicKeyOrToken
buffer.WriteString (rows [i].Col7); // Name
buffer.WriteString (rows [i].Col8); // Culture
buffer.WriteBlob (rows [i].Col9); // Hash
}
}
}
sealed class FileTable : MetadataTable<FileRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt32 ((uint) rows [i].Col1);
buffer.WriteString (rows [i].Col2);
buffer.WriteBlob (rows [i].Col3);
}
}
}
sealed class ExportedTypeTable : MetadataTable<ExportedTypeRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt32 ((uint) rows [i].Col1);
buffer.WriteUInt32 (rows [i].Col2);
buffer.WriteString (rows [i].Col3);
buffer.WriteString (rows [i].Col4);
buffer.WriteCodedRID (rows [i].Col5, CodedIndex.Implementation);
}
}
}
sealed class ManifestResourceTable : MetadataTable<ManifestResourceRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt32 (rows [i].Col1);
buffer.WriteUInt32 ((uint) rows [i].Col2);
buffer.WriteString (rows [i].Col3);
buffer.WriteCodedRID (rows [i].Col4, CodedIndex.Implementation);
}
}
}
sealed class NestedClassTable : SortedTable<NestedClassRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteRID (rows [i].Col1, Table.TypeDef); // NestedClass
buffer.WriteRID (rows [i].Col2, Table.TypeDef); // EnclosingClass
}
}
public override int Compare (NestedClassRow x, NestedClassRow y)
{
return Compare (x.Col1, y.Col1);
}
}
sealed class GenericParamTable : MetadataTable<GenericParamRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt16 (rows [i].Col1); // Number
buffer.WriteUInt16 ((ushort) rows [i].Col2); // Flags
buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeOrMethodDef); // Owner
buffer.WriteString (rows [i].Col4); // Name
}
}
}
sealed class MethodSpecTable : MetadataTable<MethodSpecRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MethodDefOrRef); // Method
buffer.WriteBlob (rows [i].Col2); // Instantiation
}
}
}
sealed class GenericParamConstraintTable : MetadataTable<GenericParamConstraintRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteRID (rows [i].Col1, Table.GenericParam); // Owner
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Constraint
}
}
}
sealed class DocumentTable : MetadataTable<DocumentRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteBlob (rows [i].Col1); // Name
buffer.WriteGuid (rows [i].Col2); // HashAlgorithm
buffer.WriteBlob (rows [i].Col3); // Hash
buffer.WriteGuid (rows [i].Col4); // Language
}
}
}
sealed class MethodDebugInformationTable : MetadataTable<MethodDebugInformationRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteRID (rows [i].Col1, Table.Document); // Document
buffer.WriteBlob (rows [i].Col2); // SequencePoints
}
}
}
sealed class LocalScopeTable : MetadataTable<LocalScopeRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteRID (rows [i].Col1, Table.Method); // Method
buffer.WriteRID (rows [i].Col2, Table.ImportScope); // ImportScope
buffer.WriteRID (rows [i].Col3, Table.LocalVariable); // VariableList
buffer.WriteRID (rows [i].Col4, Table.LocalConstant); // ConstantList
buffer.WriteUInt32 (rows [i].Col5); // StartOffset
buffer.WriteUInt32 (rows [i].Col6); // Length
}
}
}
sealed class LocalVariableTable : MetadataTable<LocalVariableRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes
buffer.WriteUInt16 (rows [i].Col2); // Index
buffer.WriteString (rows [i].Col3); // Name
}
}
}
sealed class LocalConstantTable : MetadataTable<LocalConstantRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteString (rows [i].Col1); // Name
buffer.WriteBlob (rows [i].Col2); // Signature
}
}
}
sealed class ImportScopeTable : MetadataTable<ImportScopeRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteRID (rows [i].Col1, Table.ImportScope); // Parent
buffer.WriteBlob (rows [i].Col2); // Imports
}
}
}
sealed class StateMachineMethodTable : MetadataTable<StateMachineMethodRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteRID (rows [i].Col1, Table.Method); // MoveNextMethod
buffer.WriteRID (rows [i].Col2, Table.Method); // KickoffMethod
}
}
}
sealed class CustomDebugInformationTable : SortedTable<CustomDebugInformationRow> {
public override void Write (TableHeapBuffer buffer)
{
for (int i = 0; i < length; i++) {
buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasCustomDebugInformation); // Parent
buffer.WriteGuid (rows [i].Col2); // Kind
buffer.WriteBlob (rows [i].Col3); // Value
}
}
public override int Compare (CustomDebugInformationRow x, CustomDebugInformationRow y)
{
return Compare(x.Col1, y.Col1);
}
}
sealed class MetadataBuilder {
readonly internal ModuleDefinition module;
readonly internal ISymbolWriterProvider symbol_writer_provider;
readonly internal ISymbolWriter symbol_writer;
readonly internal TextMap text_map;
readonly internal string fq_name;
readonly internal uint timestamp;
readonly Dictionary<TypeRefRow, MetadataToken> type_ref_map;
readonly Dictionary<uint, MetadataToken> type_spec_map;
readonly Dictionary<MemberRefRow, MetadataToken> member_ref_map;
readonly Dictionary<MethodSpecRow, MetadataToken> method_spec_map;
readonly Collection<GenericParameter> generic_parameters;
readonly internal CodeWriter code;
readonly internal DataBuffer data;
readonly internal ResourceBuffer resources;
readonly internal StringHeapBuffer string_heap;
readonly internal GuidHeapBuffer guid_heap;
readonly internal UserStringHeapBuffer user_string_heap;
readonly internal BlobHeapBuffer blob_heap;
readonly internal TableHeapBuffer table_heap;
readonly internal PdbHeapBuffer pdb_heap;
internal MetadataToken entry_point;
internal RID type_rid = 1;
internal RID field_rid = 1;
internal RID method_rid = 1;
internal RID param_rid = 1;
internal RID property_rid = 1;
internal RID event_rid = 1;
internal RID local_variable_rid = 1;
internal RID local_constant_rid = 1;
readonly TypeRefTable type_ref_table;
readonly TypeDefTable type_def_table;
readonly FieldTable field_table;
readonly MethodTable method_table;
readonly ParamTable param_table;
readonly InterfaceImplTable iface_impl_table;
readonly MemberRefTable member_ref_table;
readonly ConstantTable constant_table;
readonly CustomAttributeTable custom_attribute_table;
readonly DeclSecurityTable declsec_table;
readonly StandAloneSigTable standalone_sig_table;
readonly EventMapTable event_map_table;
readonly EventTable event_table;
readonly PropertyMapTable property_map_table;
readonly PropertyTable property_table;
readonly TypeSpecTable typespec_table;
readonly MethodSpecTable method_spec_table;
readonly bool portable_pdb;
internal MetadataBuilder metadata_builder;
readonly DocumentTable document_table;
readonly MethodDebugInformationTable method_debug_information_table;
readonly LocalScopeTable local_scope_table;
readonly LocalVariableTable local_variable_table;
readonly LocalConstantTable local_constant_table;
readonly ImportScopeTable import_scope_table;
readonly StateMachineMethodTable state_machine_method_table;
readonly CustomDebugInformationTable custom_debug_information_table;
readonly Dictionary<ImportScopeRow, MetadataToken> import_scope_map;
readonly Dictionary<string, MetadataToken> document_map;
public MetadataBuilder (ModuleDefinition module, string fq_name, uint timestamp, ISymbolWriterProvider symbol_writer_provider, ISymbolWriter symbol_writer)
{
this.module = module;
this.text_map = CreateTextMap ();
this.fq_name = fq_name;
this.timestamp = timestamp;
this.symbol_writer_provider = symbol_writer_provider;
if (symbol_writer == null && module.HasImage && module.Image.HasDebugTables ()) {
symbol_writer = new PortablePdbWriter (this, module);
}
this.symbol_writer = symbol_writer;
var pdb_writer = symbol_writer as IMetadataSymbolWriter;
if (pdb_writer != null) {
portable_pdb = true;
pdb_writer.SetMetadata (this);
}
this.code = new CodeWriter (this);
this.data = new DataBuffer ();
this.resources = new ResourceBuffer ();
this.string_heap = new StringHeapBuffer ();
this.guid_heap = new GuidHeapBuffer ();
this.user_string_heap = new UserStringHeapBuffer ();
this.blob_heap = new BlobHeapBuffer ();
this.table_heap = new TableHeapBuffer (module, this);
this.type_ref_table = GetTable<TypeRefTable> (Table.TypeRef);
this.type_def_table = GetTable<TypeDefTable> (Table.TypeDef);
this.field_table = GetTable<FieldTable> (Table.Field);
this.method_table = GetTable<MethodTable> (Table.Method);
this.param_table = GetTable<ParamTable> (Table.Param);
this.iface_impl_table = GetTable<InterfaceImplTable> (Table.InterfaceImpl);
this.member_ref_table = GetTable<MemberRefTable> (Table.MemberRef);
this.constant_table = GetTable<ConstantTable> (Table.Constant);
this.custom_attribute_table = GetTable<CustomAttributeTable> (Table.CustomAttribute);
this.declsec_table = GetTable<DeclSecurityTable> (Table.DeclSecurity);
this.standalone_sig_table = GetTable<StandAloneSigTable> (Table.StandAloneSig);
this.event_map_table = GetTable<EventMapTable> (Table.EventMap);
this.event_table = GetTable<EventTable> (Table.Event);
this.property_map_table = GetTable<PropertyMapTable> (Table.PropertyMap);
this.property_table = GetTable<PropertyTable> (Table.Property);
this.typespec_table = GetTable<TypeSpecTable> (Table.TypeSpec);
this.method_spec_table = GetTable<MethodSpecTable> (Table.MethodSpec);
var row_equality_comparer = new RowEqualityComparer ();
type_ref_map = new Dictionary<TypeRefRow, MetadataToken> (row_equality_comparer);
type_spec_map = new Dictionary<uint, MetadataToken> ();
member_ref_map = new Dictionary<MemberRefRow, MetadataToken> (row_equality_comparer);
method_spec_map = new Dictionary<MethodSpecRow, MetadataToken> (row_equality_comparer);
generic_parameters = new Collection<GenericParameter> ();
if (!portable_pdb)
return;
this.document_table = GetTable<DocumentTable> (Table.Document);
this.method_debug_information_table = GetTable<MethodDebugInformationTable> (Table.MethodDebugInformation);
this.local_scope_table = GetTable<LocalScopeTable> (Table.LocalScope);
this.local_variable_table = GetTable<LocalVariableTable> (Table.LocalVariable);
this.local_constant_table = GetTable<LocalConstantTable> (Table.LocalConstant);
this.import_scope_table = GetTable<ImportScopeTable> (Table.ImportScope);
this.state_machine_method_table = GetTable<StateMachineMethodTable> (Table.StateMachineMethod);
this.custom_debug_information_table = GetTable<CustomDebugInformationTable> (Table.CustomDebugInformation);
this.document_map = new Dictionary<string, MetadataToken> (StringComparer.Ordinal);
this.import_scope_map = new Dictionary<ImportScopeRow, MetadataToken> (row_equality_comparer);
}
public MetadataBuilder (ModuleDefinition module, PortablePdbWriterProvider writer_provider)
{
this.module = module;
this.text_map = new TextMap ();
this.symbol_writer_provider = writer_provider;
this.portable_pdb = true;
this.string_heap = new StringHeapBuffer ();
this.guid_heap = new GuidHeapBuffer ();
this.user_string_heap = new UserStringHeapBuffer ();
this.blob_heap = new BlobHeapBuffer ();
this.table_heap = new TableHeapBuffer (module, this);
this.pdb_heap = new PdbHeapBuffer();
this.document_table = GetTable<DocumentTable> (Table.Document);
this.method_debug_information_table = GetTable<MethodDebugInformationTable> (Table.MethodDebugInformation);
this.local_scope_table = GetTable<LocalScopeTable> (Table.LocalScope);
this.local_variable_table = GetTable<LocalVariableTable> (Table.LocalVariable);
this.local_constant_table = GetTable<LocalConstantTable> (Table.LocalConstant);
this.import_scope_table = GetTable<ImportScopeTable> (Table.ImportScope);
this.state_machine_method_table = GetTable<StateMachineMethodTable> (Table.StateMachineMethod);
this.custom_debug_information_table = GetTable<CustomDebugInformationTable> (Table.CustomDebugInformation);
var row_equality_comparer = new RowEqualityComparer ();
this.document_map = new Dictionary<string, MetadataToken> ();
this.import_scope_map = new Dictionary<ImportScopeRow, MetadataToken> (row_equality_comparer);
}
TextMap CreateTextMap ()
{
var map = new TextMap ();
map.AddMap (TextSegment.ImportAddressTable, module.Architecture == TargetArchitecture.I386 ? 8 : 0);
map.AddMap (TextSegment.CLIHeader, 0x48, 8);
return map;
}
TTable GetTable<TTable> (Table table) where TTable : MetadataTable, new ()
{
return table_heap.GetTable<TTable> (table);
}
uint GetStringIndex (string @string)
{
if (string.IsNullOrEmpty (@string))
return 0;
return string_heap.GetStringIndex (@string);
}
uint GetGuidIndex (Guid guid)
{
return guid_heap.GetGuidIndex (guid);
}
uint GetBlobIndex (ByteBuffer blob)
{
if (blob.length == 0)
return 0;
return blob_heap.GetBlobIndex (blob);
}
uint GetBlobIndex (byte [] blob)
{
if (blob.IsNullOrEmpty ())
return 0;
return GetBlobIndex (new ByteBuffer (blob));
}
public void BuildMetadata ()
{
BuildModule ();
table_heap.string_offsets = string_heap.WriteStrings ();
table_heap.ComputeTableInformations ();
table_heap.WriteTableHeap ();
}
void BuildModule ()
{
var table = GetTable<ModuleTable> (Table.Module);
table.row.Col1 = GetStringIndex (module.Name);
table.row.Col2 = GetGuidIndex (module.Mvid);
var assembly = module.Assembly;
if (assembly != null)
BuildAssembly ();
if (module.HasAssemblyReferences)
AddAssemblyReferences ();
if (module.HasModuleReferences)
AddModuleReferences ();
if (module.HasResources)
AddResources ();
if (module.HasExportedTypes)
AddExportedTypes ();
BuildTypes ();
if (assembly != null) {
if (assembly.HasCustomAttributes)
AddCustomAttributes (assembly);
if (assembly.HasSecurityDeclarations)
AddSecurityDeclarations (assembly);
}
if (module.HasCustomAttributes)
AddCustomAttributes (module);
if (module.EntryPoint != null)
entry_point = LookupToken (module.EntryPoint);
var pdb_writer = symbol_writer as IMetadataSymbolWriter;
if (pdb_writer != null)
pdb_writer.WriteModule ();
}
void BuildAssembly ()
{
var assembly = module.Assembly;
var name = assembly.Name;
var table = GetTable<AssemblyTable> (Table.Assembly);
table.row = new AssemblyRow (
name.HashAlgorithm,
(ushort) name.Version.Major,
(ushort) name.Version.Minor,
(ushort) name.Version.Build,
(ushort) name.Version.Revision,
name.Attributes,
GetBlobIndex (name.PublicKey),
GetStringIndex (name.Name),
GetStringIndex (name.Culture));
if (assembly.Modules.Count > 1)
BuildModules ();
}
void BuildModules ()
{
var modules = this.module.Assembly.Modules;
var table = GetTable<FileTable> (Table.File);
for (int i = 0; i < modules.Count; i++) {
var module = modules [i];
if (module.IsMain)
continue;
#if NET_CORE
throw new NotSupportedException ();
#else
var parameters = new WriterParameters {
SymbolWriterProvider = symbol_writer_provider,
};
var file_name = GetModuleFileName (module.Name);
module.Write (file_name, parameters);
var hash = CryptoService.ComputeHash (file_name);
table.AddRow (new FileRow (
FileAttributes.ContainsMetaData,
GetStringIndex (module.Name),
GetBlobIndex (hash)));
#endif
}
}
#if !NET_CORE
string GetModuleFileName (string name)
{
if (string.IsNullOrEmpty (name))
throw new NotSupportedException ();
var path = Path.GetDirectoryName (fq_name);
return Path.Combine (path, name);
}
#endif
void AddAssemblyReferences ()
{
var references = module.AssemblyReferences;
var table = GetTable<AssemblyRefTable> (Table.AssemblyRef);
if (module.IsWindowsMetadata ())
module.Projections.RemoveVirtualReferences (references);
for (int i = 0; i < references.Count; i++) {
var reference = references [i];
var key_or_token = reference.PublicKey.IsNullOrEmpty ()
? reference.PublicKeyToken
: reference.PublicKey;
var version = reference.Version;
var rid = table.AddRow (new AssemblyRefRow (
(ushort) version.Major,
(ushort) version.Minor,
(ushort) version.Build,
(ushort) version.Revision,
reference.Attributes,
GetBlobIndex (key_or_token),
GetStringIndex (reference.Name),
GetStringIndex (reference.Culture),
GetBlobIndex (reference.Hash)));
reference.token = new MetadataToken (TokenType.AssemblyRef, rid);
}
if (module.IsWindowsMetadata ())
module.Projections.AddVirtualReferences (references);
}
void AddModuleReferences ()
{
var references = module.ModuleReferences;
var table = GetTable<ModuleRefTable> (Table.ModuleRef);
for (int i = 0; i < references.Count; i++) {
var reference = references [i];
reference.token = new MetadataToken (
TokenType.ModuleRef,
table.AddRow (GetStringIndex (reference.Name)));
}
}
void AddResources ()
{
var resources = module.Resources;
var table = GetTable<ManifestResourceTable> (Table.ManifestResource);
for (int i = 0; i < resources.Count; i++) {
var resource = resources [i];
var row = new ManifestResourceRow (
0,
resource.Attributes,
GetStringIndex (resource.Name),
0);
switch (resource.ResourceType) {
case ResourceType.Embedded:
row.Col1 = AddEmbeddedResource ((EmbeddedResource) resource);
break;
case ResourceType.Linked:
row.Col4 = CodedIndex.Implementation.CompressMetadataToken (
new MetadataToken (
TokenType.File,
AddLinkedResource ((LinkedResource) resource)));
break;
case ResourceType.AssemblyLinked:
row.Col4 = CodedIndex.Implementation.CompressMetadataToken (
((AssemblyLinkedResource) resource).Assembly.MetadataToken);
break;
default:
throw new NotSupportedException ();
}
table.AddRow (row);
}
}
uint AddLinkedResource (LinkedResource resource)
{
var table = GetTable<FileTable> (Table.File);
var hash = resource.Hash;
#if !NET_CORE
if (hash.IsNullOrEmpty ())
hash = CryptoService.ComputeHash (resource.File);
#endif
return (uint) table.AddRow (new FileRow (
FileAttributes.ContainsNoMetaData,
GetStringIndex (resource.File),
GetBlobIndex (hash)));
}
uint AddEmbeddedResource (EmbeddedResource resource)
{
return resources.AddResource (resource.GetResourceData ());
}
void AddExportedTypes ()
{
var exported_types = module.ExportedTypes;
var table = GetTable<ExportedTypeTable> (Table.ExportedType);
for (int i = 0; i < exported_types.Count; i++) {
var exported_type = exported_types [i];
var rid = table.AddRow (new ExportedTypeRow (
exported_type.Attributes,
(uint) exported_type.Identifier,
GetStringIndex (exported_type.Name),
GetStringIndex (exported_type.Namespace),
MakeCodedRID (GetExportedTypeScope (exported_type), CodedIndex.Implementation)));
exported_type.token = new MetadataToken (TokenType.ExportedType, rid);
}
}
MetadataToken GetExportedTypeScope (ExportedType exported_type)
{
if (exported_type.DeclaringType != null)
return exported_type.DeclaringType.MetadataToken;
var scope = exported_type.Scope;
switch (scope.MetadataToken.TokenType) {
case TokenType.AssemblyRef:
return scope.MetadataToken;
case TokenType.ModuleRef:
var file_table = GetTable<FileTable> (Table.File);
for (int i = 0; i < file_table.length; i++)
if (file_table.rows [i].Col2 == GetStringIndex (scope.Name))
return new MetadataToken (TokenType.File, i + 1);
break;
}
throw new NotSupportedException ();
}
void BuildTypes ()
{
if (!module.HasTypes)
return;
AttachTokens ();
AddTypes ();
AddGenericParameters ();
}
void AttachTokens ()
{
var types = module.Types;
for (int i = 0; i < types.Count; i++)
AttachTypeToken (types [i]);
}
void AttachTypeToken (TypeDefinition type)
{
type.token = new MetadataToken (TokenType.TypeDef, type_rid++);
type.fields_range.Start = field_rid;
type.methods_range.Start = method_rid;
if (type.HasFields)
AttachFieldsToken (type);
if (type.HasMethods)
AttachMethodsToken (type);
if (type.HasNestedTypes)
AttachNestedTypesToken (type);
}
void AttachNestedTypesToken (TypeDefinition type)
{
var nested_types = type.NestedTypes;
for (int i = 0; i < nested_types.Count; i++)
AttachTypeToken (nested_types [i]);
}
void AttachFieldsToken (TypeDefinition type)
{
var fields = type.Fields;
type.fields_range.Length = (uint) fields.Count;
for (int i = 0; i < fields.Count; i++)
fields [i].token = new MetadataToken (TokenType.Field, field_rid++);
}
void AttachMethodsToken (TypeDefinition type)
{
var methods = type.Methods;
type.methods_range.Length = (uint) methods.Count;
for (int i = 0; i < methods.Count; i++)
methods [i].token = new MetadataToken (TokenType.Method, method_rid++);
}
MetadataToken GetTypeToken (TypeReference type)
{
if (type == null)
return MetadataToken.Zero;
if (type.IsDefinition)
return type.token;
if (type.IsTypeSpecification ())
return GetTypeSpecToken (type);
return GetTypeRefToken (type);
}
MetadataToken GetTypeSpecToken (TypeReference type)
{
var row = GetBlobIndex (GetTypeSpecSignature (type));
MetadataToken token;
if (type_spec_map.TryGetValue (row, out token))
return token;
return AddTypeSpecification (type, row);
}
MetadataToken AddTypeSpecification (TypeReference type, uint row)
{
type.token = new MetadataToken (TokenType.TypeSpec, typespec_table.AddRow (row));
var token = type.token;
type_spec_map.Add (row, token);
return token;
}
MetadataToken GetTypeRefToken (TypeReference type)
{
var projection = WindowsRuntimeProjections.RemoveProjection (type);
var row = CreateTypeRefRow (type);
MetadataToken token;
if (!type_ref_map.TryGetValue (row, out token))
token = AddTypeReference (type, row);
WindowsRuntimeProjections.ApplyProjection (type, projection);
return token;
}
TypeRefRow CreateTypeRefRow (TypeReference type)
{
var scope_token = GetScopeToken (type);
return new TypeRefRow (
MakeCodedRID (scope_token, CodedIndex.ResolutionScope),
GetStringIndex (type.Name),
GetStringIndex (type.Namespace));
}
MetadataToken GetScopeToken (TypeReference type)
{
if (type.IsNested)
return GetTypeRefToken (type.DeclaringType);
var scope = type.Scope;
if (scope == null)
return MetadataToken.Zero;
return scope.MetadataToken;
}
static CodedRID MakeCodedRID (IMetadataTokenProvider provider, CodedIndex index)
{
return MakeCodedRID (provider.MetadataToken, index);
}
static CodedRID MakeCodedRID (MetadataToken token, CodedIndex index)
{
return index.CompressMetadataToken (token);
}
MetadataToken AddTypeReference (TypeReference type, TypeRefRow row)
{
type.token = new MetadataToken (TokenType.TypeRef, type_ref_table.AddRow (row));
var token = type.token;
type_ref_map.Add (row, token);
return token;
}
void AddTypes ()
{
var types = module.Types;
for (int i = 0; i < types.Count; i++)
AddType (types [i]);
}
void AddType (TypeDefinition type)
{
var treatment = WindowsRuntimeProjections.RemoveProjection (type);
type_def_table.AddRow (new TypeDefRow (
type.Attributes,
GetStringIndex (type.Name),
GetStringIndex (type.Namespace),
MakeCodedRID (GetTypeToken (type.BaseType), CodedIndex.TypeDefOrRef),
type.fields_range.Start,
type.methods_range.Start));
if (type.HasGenericParameters)
AddGenericParameters (type);
if (type.HasInterfaces)
AddInterfaces (type);
AddLayoutInfo (type);
if (type.HasFields)
AddFields (type);
if (type.HasMethods)
AddMethods (type);
if (type.HasProperties)
AddProperties (type);
if (type.HasEvents)
AddEvents (type);
if (type.HasCustomAttributes)
AddCustomAttributes (type);
if (type.HasSecurityDeclarations)
AddSecurityDeclarations (type);
if (type.HasNestedTypes)
AddNestedTypes (type);
WindowsRuntimeProjections.ApplyProjection (type, treatment);
}
void AddGenericParameters (IGenericParameterProvider owner)
{
var parameters = owner.GenericParameters;
for (int i = 0; i < parameters.Count; i++)
generic_parameters.Add (parameters [i]);
}
sealed class GenericParameterComparer : IComparer<GenericParameter> {
public int Compare (GenericParameter a, GenericParameter b)
{
var a_owner = MakeCodedRID (a.Owner, CodedIndex.TypeOrMethodDef);
var b_owner = MakeCodedRID (b.Owner, CodedIndex.TypeOrMethodDef);
if (a_owner == b_owner) {
var a_pos = a.Position;
var b_pos = b.Position;
return a_pos == b_pos ? 0 : a_pos > b_pos ? 1 : -1;
}
return a_owner > b_owner ? 1 : -1;
}
}
void AddGenericParameters ()
{
var items = this.generic_parameters.items;
var size = this.generic_parameters.size;
Array.Sort (items, 0, size, new GenericParameterComparer ());
var generic_param_table = GetTable<GenericParamTable> (Table.GenericParam);
var generic_param_constraint_table = GetTable<GenericParamConstraintTable> (Table.GenericParamConstraint);
for (int i = 0; i < size; i++) {
var generic_parameter = items [i];
var rid = generic_param_table.AddRow (new GenericParamRow (
(ushort) generic_parameter.Position,
generic_parameter.Attributes,
MakeCodedRID (generic_parameter.Owner, CodedIndex.TypeOrMethodDef),
GetStringIndex (generic_parameter.Name)));
generic_parameter.token = new MetadataToken (TokenType.GenericParam, rid);
if (generic_parameter.HasConstraints)
AddConstraints (generic_parameter, generic_param_constraint_table);
if (generic_parameter.HasCustomAttributes)
AddCustomAttributes (generic_parameter);
}
}
void AddConstraints (GenericParameter generic_parameter, GenericParamConstraintTable table)
{
var constraints = generic_parameter.Constraints;
var rid = generic_parameter.token.RID;
for (int i = 0; i < constraints.Count; i++)
table.AddRow (new GenericParamConstraintRow (
rid,
MakeCodedRID (GetTypeToken (constraints [i]), CodedIndex.TypeDefOrRef)));
}
void AddInterfaces (TypeDefinition type)
{
var interfaces = type.Interfaces;
var type_rid = type.token.RID;
for (int i = 0; i < interfaces.Count; i++) {
var iface_impl = interfaces [i];
var rid = iface_impl_table.AddRow (new InterfaceImplRow (
type_rid,
MakeCodedRID (GetTypeToken (iface_impl.InterfaceType), CodedIndex.TypeDefOrRef)));
iface_impl.token = new MetadataToken (TokenType.InterfaceImpl, rid);
if (iface_impl.HasCustomAttributes)
AddCustomAttributes (iface_impl);
}
}
void AddLayoutInfo (TypeDefinition type)
{
if (type.HasLayoutInfo) {
var table = GetTable<ClassLayoutTable> (Table.ClassLayout);
table.AddRow (new ClassLayoutRow (
(ushort) type.PackingSize,
(uint) type.ClassSize,
type.token.RID));
return;
}
if (type.IsValueType && HasNoInstanceField (type)) {
var table = GetTable<ClassLayoutTable> (Table.ClassLayout);
table.AddRow (new ClassLayoutRow (0, 1, type.token.RID));
}
}
static bool HasNoInstanceField (TypeDefinition type)
{
if (!type.HasFields)
return true;
var fields = type.Fields;
for (int i = 0; i < fields.Count; i++)
if (!fields [i].IsStatic)
return false;
return true;
}
void AddNestedTypes (TypeDefinition type)
{
var nested_types = type.NestedTypes;
var nested_table = GetTable<NestedClassTable> (Table.NestedClass);
for (int i = 0; i < nested_types.Count; i++) {
var nested = nested_types [i];
AddType (nested);
nested_table.AddRow (new NestedClassRow (nested.token.RID, type.token.RID));
}
}
void AddFields (TypeDefinition type)
{
var fields = type.Fields;
for (int i = 0; i < fields.Count; i++)
AddField (fields [i]);
}
void AddField (FieldDefinition field)
{
var projection = WindowsRuntimeProjections.RemoveProjection (field);
field_table.AddRow (new FieldRow (
field.Attributes,
GetStringIndex (field.Name),
GetBlobIndex (GetFieldSignature (field))));
if (!field.InitialValue.IsNullOrEmpty ())
AddFieldRVA (field);
if (field.HasLayoutInfo)
AddFieldLayout (field);
if (field.HasCustomAttributes)
AddCustomAttributes (field);
if (field.HasConstant)
AddConstant (field, field.FieldType);
if (field.HasMarshalInfo)
AddMarshalInfo (field);
WindowsRuntimeProjections.ApplyProjection (field, projection);
}
void AddFieldRVA (FieldDefinition field)
{
var table = GetTable<FieldRVATable> (Table.FieldRVA);
table.AddRow (new FieldRVARow (
data.AddData (field.InitialValue),
field.token.RID));
}
void AddFieldLayout (FieldDefinition field)
{
var table = GetTable<FieldLayoutTable> (Table.FieldLayout);
table.AddRow (new FieldLayoutRow ((uint) field.Offset, field.token.RID));
}
void AddMethods (TypeDefinition type)
{
var methods = type.Methods;
for (int i = 0; i < methods.Count; i++)
AddMethod (methods [i]);
}
void AddMethod (MethodDefinition method)
{
var projection = WindowsRuntimeProjections.RemoveProjection (method);
method_table.AddRow (new MethodRow (
method.HasBody ? code.WriteMethodBody (method) : 0,
method.ImplAttributes,
method.Attributes,
GetStringIndex (method.Name),
GetBlobIndex (GetMethodSignature (method)),
param_rid));
AddParameters (method);
if (method.HasGenericParameters)
AddGenericParameters (method);
if (method.IsPInvokeImpl)
AddPInvokeInfo (method);
if (method.HasCustomAttributes)
AddCustomAttributes (method);
if (method.HasSecurityDeclarations)
AddSecurityDeclarations (method);
if (method.HasOverrides)
AddOverrides (method);
WindowsRuntimeProjections.ApplyProjection (method, projection);
}
void AddParameters (MethodDefinition method)
{
var return_parameter = method.MethodReturnType.parameter;
if (return_parameter != null && RequiresParameterRow (return_parameter))
AddParameter (0, return_parameter, param_table);
if (!method.HasParameters)
return;
var parameters = method.Parameters;
for (int i = 0; i < parameters.Count; i++) {
var parameter = parameters [i];
if (!RequiresParameterRow (parameter))
continue;
AddParameter ((ushort) (i + 1), parameter, param_table);
}
}
void AddPInvokeInfo (MethodDefinition method)
{
var pinvoke = method.PInvokeInfo;
if (pinvoke == null)
return;
var table = GetTable<ImplMapTable> (Table.ImplMap);
table.AddRow (new ImplMapRow (
pinvoke.Attributes,
MakeCodedRID (method, CodedIndex.MemberForwarded),
GetStringIndex (pinvoke.EntryPoint),
pinvoke.Module.MetadataToken.RID));
}
void AddOverrides (MethodDefinition method)
{
var overrides = method.Overrides;
var table = GetTable<MethodImplTable> (Table.MethodImpl);
for (int i = 0; i < overrides.Count; i++) {
table.AddRow (new MethodImplRow (
method.DeclaringType.token.RID,
MakeCodedRID (method, CodedIndex.MethodDefOrRef),
MakeCodedRID (LookupToken (overrides [i]), CodedIndex.MethodDefOrRef)));
}
}
static bool RequiresParameterRow (ParameterDefinition parameter)
{
return !string.IsNullOrEmpty (parameter.Name)
|| parameter.Attributes != ParameterAttributes.None
|| parameter.HasMarshalInfo
|| parameter.HasConstant
|| parameter.HasCustomAttributes;
}
void AddParameter (ushort sequence, ParameterDefinition parameter, ParamTable table)
{
table.AddRow (new ParamRow (
parameter.Attributes,
sequence,
GetStringIndex (parameter.Name)));
parameter.token = new MetadataToken (TokenType.Param, param_rid++);
if (parameter.HasCustomAttributes)
AddCustomAttributes (parameter);
if (parameter.HasConstant)
AddConstant (parameter, parameter.ParameterType);
if (parameter.HasMarshalInfo)
AddMarshalInfo (parameter);
}
void AddMarshalInfo (IMarshalInfoProvider owner)
{
var table = GetTable<FieldMarshalTable> (Table.FieldMarshal);
table.AddRow (new FieldMarshalRow (
MakeCodedRID (owner, CodedIndex.HasFieldMarshal),
GetBlobIndex (GetMarshalInfoSignature (owner))));
}
void AddProperties (TypeDefinition type)
{
var properties = type.Properties;
property_map_table.AddRow (new PropertyMapRow (type.token.RID, property_rid));
for (int i = 0; i < properties.Count; i++)
AddProperty (properties [i]);
}
void AddProperty (PropertyDefinition property)
{
property_table.AddRow (new PropertyRow (
property.Attributes,
GetStringIndex (property.Name),
GetBlobIndex (GetPropertySignature (property))));
property.token = new MetadataToken (TokenType.Property, property_rid++);
var method = property.GetMethod;
if (method != null)
AddSemantic (MethodSemanticsAttributes.Getter, property, method);
method = property.SetMethod;
if (method != null)
AddSemantic (MethodSemanticsAttributes.Setter, property, method);
if (property.HasOtherMethods)
AddOtherSemantic (property, property.OtherMethods);
if (property.HasCustomAttributes)
AddCustomAttributes (property);
if (property.HasConstant)
AddConstant (property, property.PropertyType);
}
void AddOtherSemantic (IMetadataTokenProvider owner, Collection<MethodDefinition> others)
{
for (int i = 0; i < others.Count; i++)
AddSemantic (MethodSemanticsAttributes.Other, owner, others [i]);
}
void AddEvents (TypeDefinition type)
{
var events = type.Events;
event_map_table.AddRow (new EventMapRow (type.token.RID, event_rid));
for (int i = 0; i < events.Count; i++)
AddEvent (events [i]);
}
void AddEvent (EventDefinition @event)
{
event_table.AddRow (new EventRow (
@event.Attributes,
GetStringIndex (@event.Name),
MakeCodedRID (GetTypeToken (@event.EventType), CodedIndex.TypeDefOrRef)));
@event.token = new MetadataToken (TokenType.Event, event_rid++);
var method = @event.AddMethod;
if (method != null)
AddSemantic (MethodSemanticsAttributes.AddOn, @event, method);
method = @event.InvokeMethod;
if (method != null)
AddSemantic (MethodSemanticsAttributes.Fire, @event, method);
method = @event.RemoveMethod;
if (method != null)
AddSemantic (MethodSemanticsAttributes.RemoveOn, @event, method);
if (@event.HasOtherMethods)
AddOtherSemantic (@event, @event.OtherMethods);
if (@event.HasCustomAttributes)
AddCustomAttributes (@event);
}
void AddSemantic (MethodSemanticsAttributes semantics, IMetadataTokenProvider provider, MethodDefinition method)
{
method.SemanticsAttributes = semantics;
var table = GetTable<MethodSemanticsTable> (Table.MethodSemantics);
table.AddRow (new MethodSemanticsRow (
semantics,
method.token.RID,
MakeCodedRID (provider, CodedIndex.HasSemantics)));
}
void AddConstant (IConstantProvider owner, TypeReference type)
{
var constant = owner.Constant;
var etype = GetConstantType (type, constant);
constant_table.AddRow (new ConstantRow (
etype,
MakeCodedRID (owner.MetadataToken, CodedIndex.HasConstant),
GetBlobIndex (GetConstantSignature (etype, constant))));
}
static ElementType GetConstantType (TypeReference constant_type, object constant)
{
if (constant == null)
return ElementType.Class;
var etype = constant_type.etype;
switch (etype) {
case ElementType.None:
var type = constant_type.CheckedResolve ();
if (type.IsEnum)
return GetConstantType (type.GetEnumUnderlyingType (), constant);
return ElementType.Class;
case ElementType.String:
return ElementType.String;
case ElementType.Object:
return GetConstantType (constant.GetType ());
case ElementType.Array:
case ElementType.SzArray:
case ElementType.MVar:
case ElementType.Var:
return ElementType.Class;
case ElementType.GenericInst:
var generic_instance = (GenericInstanceType) constant_type;
if (generic_instance.ElementType.IsTypeOf ("System", "Nullable`1"))
return GetConstantType (generic_instance.GenericArguments [0], constant);
return GetConstantType (((TypeSpecification) constant_type).ElementType, constant);
case ElementType.CModOpt:
case ElementType.CModReqD:
case ElementType.ByRef:
case ElementType.Sentinel:
return GetConstantType (((TypeSpecification) constant_type).ElementType, constant);
case ElementType.Boolean:
case ElementType.Char:
case ElementType.I:
case ElementType.I1:
case ElementType.I2:
case ElementType.I4:
case ElementType.I8:
case ElementType.U:
case ElementType.U1:
case ElementType.U2:
case ElementType.U4:
case ElementType.U8:
case ElementType.R4:
case ElementType.R8:
return GetConstantType (constant.GetType ());
default:
return etype;
}
}
static ElementType GetConstantType (Type type)
{
switch (type.GetTypeCode ()) {
case TypeCode.Boolean:
return ElementType.Boolean;
case TypeCode.Byte:
return ElementType.U1;
case TypeCode.SByte:
return ElementType.I1;
case TypeCode.Char:
return ElementType.Char;
case TypeCode.Int16:
return ElementType.I2;
case TypeCode.UInt16:
return ElementType.U2;
case TypeCode.Int32:
return ElementType.I4;
case TypeCode.UInt32:
return ElementType.U4;
case TypeCode.Int64:
return ElementType.I8;
case TypeCode.UInt64:
return ElementType.U8;
case TypeCode.Single:
return ElementType.R4;
case TypeCode.Double:
return ElementType.R8;
case TypeCode.String:
return ElementType.String;
default:
throw new NotSupportedException (type.FullName);
}
}
void AddCustomAttributes (ICustomAttributeProvider owner)
{
var custom_attributes = owner.CustomAttributes;
for (int i = 0; i < custom_attributes.Count; i++) {
var attribute = custom_attributes [i];
var projection = WindowsRuntimeProjections.RemoveProjection (attribute);
custom_attribute_table.AddRow (new CustomAttributeRow (
MakeCodedRID (owner, CodedIndex.HasCustomAttribute),
MakeCodedRID (LookupToken (attribute.Constructor), CodedIndex.CustomAttributeType),
GetBlobIndex (GetCustomAttributeSignature (attribute))));
WindowsRuntimeProjections.ApplyProjection (attribute, projection);
}
}
void AddSecurityDeclarations (ISecurityDeclarationProvider owner)
{
var declarations = owner.SecurityDeclarations;
for (int i = 0; i < declarations.Count; i++) {
var declaration = declarations [i];
declsec_table.AddRow (new DeclSecurityRow (
declaration.Action,
MakeCodedRID (owner, CodedIndex.HasDeclSecurity),
GetBlobIndex (GetSecurityDeclarationSignature (declaration))));
}
}
MetadataToken GetMemberRefToken (MemberReference member)
{
var projection = WindowsRuntimeProjections.RemoveProjection (member);
var row = CreateMemberRefRow (member);
MetadataToken token;
if (!member_ref_map.TryGetValue (row, out token))
token = AddMemberReference (member, row);
WindowsRuntimeProjections.ApplyProjection (member, projection);
return token;
}
MemberRefRow CreateMemberRefRow (MemberReference member)
{
return new MemberRefRow (
MakeCodedRID (GetTypeToken (member.DeclaringType), CodedIndex.MemberRefParent),
GetStringIndex (member.Name),
GetBlobIndex (GetMemberRefSignature (member)));
}
MetadataToken AddMemberReference (MemberReference member, MemberRefRow row)
{
member.token = new MetadataToken (TokenType.MemberRef, member_ref_table.AddRow (row));
var token = member.token;
member_ref_map.Add (row, token);
return token;
}
MetadataToken GetMethodSpecToken (MethodSpecification method_spec)
{
var row = CreateMethodSpecRow (method_spec);
MetadataToken token;
if (method_spec_map.TryGetValue (row, out token))
return token;
AddMethodSpecification (method_spec, row);
return method_spec.token;
}
void AddMethodSpecification (MethodSpecification method_spec, MethodSpecRow row)
{
method_spec.token = new MetadataToken (TokenType.MethodSpec, method_spec_table.AddRow (row));
method_spec_map.Add (row, method_spec.token);
}
MethodSpecRow CreateMethodSpecRow (MethodSpecification method_spec)
{
return new MethodSpecRow (
MakeCodedRID (LookupToken (method_spec.ElementMethod), CodedIndex.MethodDefOrRef),
GetBlobIndex (GetMethodSpecSignature (method_spec)));
}
SignatureWriter CreateSignatureWriter ()
{
return new SignatureWriter (this);
}
SignatureWriter GetMethodSpecSignature (MethodSpecification method_spec)
{
if (!method_spec.IsGenericInstance)
throw new NotSupportedException ();
var generic_instance = (GenericInstanceMethod) method_spec;
var signature = CreateSignatureWriter ();
signature.WriteByte (0x0a);
signature.WriteGenericInstanceSignature (generic_instance);
return signature;
}
public uint AddStandAloneSignature (uint signature)
{
return (uint) standalone_sig_table.AddRow (signature);
}
public uint GetLocalVariableBlobIndex (Collection<VariableDefinition> variables)
{
return GetBlobIndex (GetVariablesSignature (variables));
}
public uint GetCallSiteBlobIndex (CallSite call_site)
{
return GetBlobIndex (GetMethodSignature (call_site));
}
public uint GetConstantTypeBlobIndex (TypeReference constant_type)
{
return GetBlobIndex (GetConstantTypeSignature (constant_type));
}
SignatureWriter GetVariablesSignature (Collection<VariableDefinition> variables)
{
var signature = CreateSignatureWriter ();
signature.WriteByte (0x7);
signature.WriteCompressedUInt32 ((uint) variables.Count);
for (int i = 0; i < variables.Count; i++)
signature.WriteTypeSignature (variables [i].VariableType);
return signature;
}
SignatureWriter GetConstantTypeSignature (TypeReference constant_type)
{
var signature = CreateSignatureWriter ();
signature.WriteByte (0x6);
signature.WriteTypeSignature (constant_type);
return signature;
}
SignatureWriter GetFieldSignature (FieldReference field)
{
var signature = CreateSignatureWriter ();
signature.WriteByte (0x6);
signature.WriteTypeSignature (field.FieldType);
return signature;
}
SignatureWriter GetMethodSignature (IMethodSignature method)
{
var signature = CreateSignatureWriter ();
signature.WriteMethodSignature (method);
return signature;
}
SignatureWriter GetMemberRefSignature (MemberReference member)
{
var field = member as FieldReference;
if (field != null)
return GetFieldSignature (field);
var method = member as MethodReference;
if (method != null)
return GetMethodSignature (method);
throw new NotSupportedException ();
}
SignatureWriter GetPropertySignature (PropertyDefinition property)
{
var signature = CreateSignatureWriter ();
byte calling_convention = 0x8;
if (property.HasThis)
calling_convention |= 0x20;
uint param_count = 0;
Collection<ParameterDefinition> parameters = null;
if (property.HasParameters) {
parameters = property.Parameters;
param_count = (uint) parameters.Count;
}
signature.WriteByte (calling_convention);
signature.WriteCompressedUInt32 (param_count);
signature.WriteTypeSignature (property.PropertyType);
if (param_count == 0)
return signature;
for (int i = 0; i < param_count; i++)
signature.WriteTypeSignature (parameters [i].ParameterType);
return signature;
}
SignatureWriter GetTypeSpecSignature (TypeReference type)
{
var signature = CreateSignatureWriter ();
signature.WriteTypeSignature (type);
return signature;
}
SignatureWriter GetConstantSignature (ElementType type, object value)
{
var signature = CreateSignatureWriter ();
switch (type) {
case ElementType.Array:
case ElementType.SzArray:
case ElementType.Class:
case ElementType.Object:
case ElementType.None:
case ElementType.Var:
case ElementType.MVar:
signature.WriteInt32 (0);
break;
case ElementType.String:
signature.WriteConstantString ((string) value);
break;
default:
signature.WriteConstantPrimitive (value);
break;
}
return signature;
}
SignatureWriter GetCustomAttributeSignature (CustomAttribute attribute)
{
var signature = CreateSignatureWriter ();
if (!attribute.resolved) {
signature.WriteBytes (attribute.GetBlob ());
return signature;
}
signature.WriteUInt16 (0x0001);
signature.WriteCustomAttributeConstructorArguments (attribute);
signature.WriteCustomAttributeNamedArguments (attribute);
return signature;
}
SignatureWriter GetSecurityDeclarationSignature (SecurityDeclaration declaration)
{
var signature = CreateSignatureWriter ();
if (!declaration.resolved)
signature.WriteBytes (declaration.GetBlob ());
else if (module.Runtime < TargetRuntime.Net_2_0)
signature.WriteXmlSecurityDeclaration (declaration);
else
signature.WriteSecurityDeclaration (declaration);
return signature;
}
SignatureWriter GetMarshalInfoSignature (IMarshalInfoProvider owner)
{
var signature = CreateSignatureWriter ();
signature.WriteMarshalInfo (owner.MarshalInfo);
return signature;
}
static Exception CreateForeignMemberException (MemberReference member)
{
return new ArgumentException (string.Format ("Member '{0}' is declared in another module and needs to be imported", member));
}
public MetadataToken LookupToken (IMetadataTokenProvider provider)
{
if (provider == null)
throw new ArgumentNullException ();
if (metadata_builder != null)
return metadata_builder.LookupToken (provider);
var member = provider as MemberReference;
if (member == null || member.Module != module)
throw CreateForeignMemberException (member);
var token = provider.MetadataToken;
switch (token.TokenType) {
case TokenType.TypeDef:
case TokenType.Method:
case TokenType.Field:
case TokenType.Event:
case TokenType.Property:
return token;
case TokenType.TypeRef:
case TokenType.TypeSpec:
case TokenType.GenericParam:
return GetTypeToken ((TypeReference) provider);
case TokenType.MethodSpec:
return GetMethodSpecToken ((MethodSpecification) provider);
case TokenType.MemberRef:
return GetMemberRefToken (member);
default:
throw new NotSupportedException ();
}
}
public void AddMethodDebugInformation (MethodDebugInformation method_info)
{
if (method_info.HasSequencePoints)
AddSequencePoints (method_info);
if (method_info.Scope != null)
AddLocalScope (method_info, method_info.Scope);
if (method_info.StateMachineKickOffMethod != null)
AddStateMachineMethod (method_info);
AddCustomDebugInformations (method_info.Method);
}
void AddStateMachineMethod (MethodDebugInformation method_info)
{
state_machine_method_table.AddRow (new StateMachineMethodRow (method_info.Method.MetadataToken.RID, method_info.StateMachineKickOffMethod.MetadataToken.RID));
}
void AddLocalScope (MethodDebugInformation method_info, ScopeDebugInformation scope)
{
var rid = local_scope_table.AddRow (new LocalScopeRow (
method_info.Method.MetadataToken.RID,
scope.import != null ? AddImportScope (scope.import) : 0,
local_variable_rid,
local_constant_rid,
(uint) scope.Start.Offset,
(uint) ((scope.End.IsEndOfMethod ? method_info.code_size : scope.End.Offset) - scope.Start.Offset)));
scope.token = new MetadataToken (TokenType.LocalScope, rid);
AddCustomDebugInformations (scope);
if (scope.HasVariables)
AddLocalVariables (scope);
if (scope.HasConstants)
AddLocalConstants (scope);
for (int i = 0; i < scope.Scopes.Count; i++)
AddLocalScope (method_info, scope.Scopes [i]);
}
void AddLocalVariables (ScopeDebugInformation scope)
{
for (int i = 0; i < scope.Variables.Count; i++) {
var variable = scope.Variables [i];
local_variable_table.AddRow (new LocalVariableRow (variable.Attributes, (ushort) variable.Index, GetStringIndex (variable.Name)));
variable.token = new MetadataToken (TokenType.LocalVariable, local_variable_rid);
local_variable_rid++;
AddCustomDebugInformations (variable);
}
}
void AddLocalConstants (ScopeDebugInformation scope)
{
for (int i = 0; i < scope.Constants.Count; i++) {
var constant = scope.Constants [i];
local_constant_table.AddRow (new LocalConstantRow (GetStringIndex (constant.Name), GetBlobIndex (GetConstantSignature(constant))));
constant.token = new MetadataToken (TokenType.LocalConstant, local_constant_rid);
local_constant_rid++;
}
}
SignatureWriter GetConstantSignature (ConstantDebugInformation constant)
{
var type = constant.ConstantType;
var signature = CreateSignatureWriter ();
signature.WriteTypeSignature (type);
if (type.IsTypeOf ("System", "Decimal")) {
var bits = decimal.GetBits ((decimal) constant.Value);
var low = (uint) bits [0];
var mid = (uint) bits [1];
var high = (uint) bits [2];
var scale = (byte) (bits [3] >> 16);
var negative = (bits [3] & 0x80000000) != 0;
signature.WriteByte ((byte) (scale | (negative ? 0x80 : 0x00)));
signature.WriteUInt32 (low);
signature.WriteUInt32 (mid);
signature.WriteUInt32 (high);
return signature;
}
if (type.IsTypeOf ("System", "DateTime")) {
var date = (DateTime) constant.Value;
signature.WriteInt64 (date.Ticks);
return signature;
}
signature.WriteBytes (GetConstantSignature (type.etype, constant.Value));
return signature;
}
public void AddCustomDebugInformations (ICustomDebugInformationProvider provider)
{
if (!provider.HasCustomDebugInformations)
return;
var custom_infos = provider.CustomDebugInformations;
for (int i = 0; i < custom_infos.Count; i++) {
var custom_info = custom_infos [i];
switch (custom_info.Kind) {
case CustomDebugInformationKind.Binary:
var binary_info = (BinaryCustomDebugInformation) custom_info;
AddCustomDebugInformation (provider, binary_info, GetBlobIndex (binary_info.Data));
break;
case CustomDebugInformationKind.AsyncMethodBody:
AddAsyncMethodBodyDebugInformation (provider, (AsyncMethodBodyDebugInformation) custom_info);
break;
case CustomDebugInformationKind.StateMachineScope:
AddStateMachineScopeDebugInformation (provider, (StateMachineScopeDebugInformation) custom_info);
break;
case CustomDebugInformationKind.EmbeddedSource:
AddEmbeddedSourceDebugInformation (provider, (EmbeddedSourceDebugInformation) custom_info);
break;
case CustomDebugInformationKind.SourceLink:
AddSourceLinkDebugInformation (provider, (SourceLinkDebugInformation) custom_info);
break;
default:
throw new NotImplementedException ();
}
}
}
void AddStateMachineScopeDebugInformation (ICustomDebugInformationProvider provider, StateMachineScopeDebugInformation state_machine_scope)
{
var method_info = ((MethodDefinition) provider).DebugInformation;
var signature = CreateSignatureWriter ();
var scopes = state_machine_scope.Scopes;
for (int i = 0; i < scopes.Count; i++) {
var scope = scopes [i];
signature.WriteUInt32 ((uint) scope.Start.Offset);
var end_offset = scope.End.IsEndOfMethod
? method_info.code_size
: scope.End.Offset;
signature.WriteUInt32 ((uint) (end_offset - scope.Start.Offset));
}
AddCustomDebugInformation (provider, state_machine_scope, signature);
}
void AddAsyncMethodBodyDebugInformation (ICustomDebugInformationProvider provider, AsyncMethodBodyDebugInformation async_method)
{
var signature = CreateSignatureWriter ();
signature.WriteUInt32 ((uint) async_method.catch_handler.Offset + 1);
if (!async_method.yields.IsNullOrEmpty ()) {
for (int i = 0; i < async_method.yields.Count; i++) {
signature.WriteUInt32 ((uint) async_method.yields [i].Offset);
signature.WriteUInt32 ((uint) async_method.resumes [i].Offset);
signature.WriteCompressedUInt32 (async_method.resume_methods [i].MetadataToken.RID);
}
}
AddCustomDebugInformation (provider, async_method, signature);
}
void AddEmbeddedSourceDebugInformation (ICustomDebugInformationProvider provider, EmbeddedSourceDebugInformation embedded_source)
{
var signature = CreateSignatureWriter ();
var content = embedded_source.content ?? Empty<byte>.Array;
if (embedded_source.compress) {
signature.WriteInt32 (content.Length);
var decompressed_stream = new MemoryStream (content);
var content_stream = new MemoryStream ();
using (var compress_stream = new DeflateStream (content_stream, CompressionMode.Compress, leaveOpen: true))
decompressed_stream.CopyTo (compress_stream);
signature.WriteBytes (content_stream.ToArray ());
} else {
signature.WriteInt32 (0);
signature.WriteBytes (content);
}
AddCustomDebugInformation (provider, embedded_source, signature);
}
void AddSourceLinkDebugInformation (ICustomDebugInformationProvider provider, SourceLinkDebugInformation source_link)
{
var signature = CreateSignatureWriter ();
signature.WriteBytes (Encoding.UTF8.GetBytes (source_link.content));
AddCustomDebugInformation (provider, source_link, signature);
}
void AddCustomDebugInformation (ICustomDebugInformationProvider provider, CustomDebugInformation custom_info, SignatureWriter signature)
{
AddCustomDebugInformation (provider, custom_info, GetBlobIndex (signature));
}
void AddCustomDebugInformation (ICustomDebugInformationProvider provider, CustomDebugInformation custom_info, uint blob_index)
{
var rid = custom_debug_information_table.AddRow (new CustomDebugInformationRow (
MakeCodedRID (provider.MetadataToken, CodedIndex.HasCustomDebugInformation),
GetGuidIndex (custom_info.Identifier),
blob_index));
custom_info.token = new MetadataToken (TokenType.CustomDebugInformation, rid);
}
uint AddImportScope (ImportDebugInformation import)
{
uint parent = 0;
if (import.Parent != null)
parent = AddImportScope (import.Parent);
uint targets_index = 0;
if (import.HasTargets) {
var signature = CreateSignatureWriter ();
for (int i = 0; i < import.Targets.Count; i++)
AddImportTarget (import.Targets [i], signature);
targets_index = GetBlobIndex (signature);
}
var row = new ImportScopeRow (parent, targets_index);
MetadataToken import_token;
if (import_scope_map.TryGetValue (row, out import_token))
return import_token.RID;
import_token = new MetadataToken (TokenType.ImportScope, import_scope_table.AddRow (row));
import_scope_map.Add (row, import_token);
return import_token.RID;
}
void AddImportTarget (ImportTarget target, SignatureWriter signature)
{
signature.WriteCompressedUInt32 ((uint)target.kind);
switch (target.kind) {
case ImportTargetKind.ImportNamespace:
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace));
break;
case ImportTargetKind.ImportNamespaceInAssembly:
signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID);
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace));
break;
case ImportTargetKind.ImportType:
signature.WriteTypeToken (target.type);
break;
case ImportTargetKind.ImportXmlNamespaceWithAlias:
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace));
break;
case ImportTargetKind.ImportAlias:
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
break;
case ImportTargetKind.DefineAssemblyAlias:
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID);
break;
case ImportTargetKind.DefineNamespaceAlias:
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace));
break;
case ImportTargetKind.DefineNamespaceInAssemblyAlias:
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID);
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace));
break;
case ImportTargetKind.DefineTypeAlias:
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
signature.WriteTypeToken (target.type);
break;
}
}
uint GetUTF8StringBlobIndex (string s)
{
return GetBlobIndex (Encoding.UTF8.GetBytes (s));
}
public MetadataToken GetDocumentToken (Document document)
{
MetadataToken token;
if (document_map.TryGetValue (document.Url, out token))
return token;
token = new MetadataToken (TokenType.Document, document_table.AddRow (
new DocumentRow (GetBlobIndex (GetDocumentNameSignature (document)),
GetGuidIndex (document.HashAlgorithm.ToGuid ()),
GetBlobIndex (document.Hash),
GetGuidIndex (document.Language.ToGuid ()))));
document.token = token;
AddCustomDebugInformations (document);
document_map.Add (document.Url, token);
return token;
}
SignatureWriter GetDocumentNameSignature (Document document)
{
var name = document.Url;
var signature = CreateSignatureWriter ();
char separator;
if (!TryGetDocumentNameSeparator (name, out separator)) {
signature.WriteByte (0);
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (name));
return signature;
}
signature.WriteByte ((byte) separator);
var parts = name.Split (new [] { separator });
for (int i = 0; i < parts.Length; i++) {
if (parts [i] == String.Empty)
signature.WriteCompressedUInt32 (0);
else
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (parts [i]));
}
return signature;
}
static bool TryGetDocumentNameSeparator (string path, out char separator)
{
const char unix = '/';
const char win = '\\';
const char zero = (char) 0;
separator = zero;
if (string.IsNullOrEmpty (path))
return false;
int unix_count = 0;
int win_count = 0;
for (int i = 0; i < path.Length; i++) {
if (path [i] == unix)
unix_count++;
else if (path [i] == win)
win_count++;
}
if (unix_count == 0 && win_count == 0)
return false;
if (unix_count >= win_count) {
separator = unix;
return true;
}
separator = win;
return true;
}
void AddSequencePoints (MethodDebugInformation info)
{
var rid = info.Method.MetadataToken.RID;
Document document;
if (info.TryGetUniqueDocument (out document))
method_debug_information_table.rows [rid - 1].Col1 = GetDocumentToken (document).RID;
var signature = CreateSignatureWriter ();
signature.WriteSequencePoints (info);
method_debug_information_table.rows [rid - 1].Col2 = GetBlobIndex (signature);
}
}
sealed class SignatureWriter : ByteBuffer {
readonly MetadataBuilder metadata;
public SignatureWriter (MetadataBuilder metadata)
: base (6)
{
this.metadata = metadata;
}
public void WriteElementType (ElementType element_type)
{
WriteByte ((byte) element_type);
}
public void WriteUTF8String (string @string)
{
if (@string == null) {
WriteByte (0xff);
return;
}
var bytes = Encoding.UTF8.GetBytes (@string);
WriteCompressedUInt32 ((uint) bytes.Length);
WriteBytes (bytes);
}
public void WriteMethodSignature (IMethodSignature method)
{
byte calling_convention = (byte) method.CallingConvention;
if (method.HasThis)
calling_convention |= 0x20;
if (method.ExplicitThis)
calling_convention |= 0x40;
var generic_provider = method as IGenericParameterProvider;
var generic_arity = generic_provider != null && generic_provider.HasGenericParameters
? generic_provider.GenericParameters.Count
: 0;
if (generic_arity > 0)
calling_convention |= 0x10;
var param_count = method.HasParameters ? method.Parameters.Count : 0;
WriteByte (calling_convention);
if (generic_arity > 0)
WriteCompressedUInt32 ((uint) generic_arity);
WriteCompressedUInt32 ((uint) param_count);
WriteTypeSignature (method.ReturnType);
if (param_count == 0)
return;
var parameters = method.Parameters;
for (int i = 0; i < param_count; i++)
WriteTypeSignature (parameters [i].ParameterType);
}
uint MakeTypeDefOrRefCodedRID (TypeReference type)
{
return CodedIndex.TypeDefOrRef.CompressMetadataToken (metadata.LookupToken (type));
}
public void WriteTypeToken (TypeReference type)
{
WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type));
}
public void WriteTypeSignature (TypeReference type)
{
if (type == null)
throw new ArgumentNullException ();
var etype = type.etype;
switch (etype) {
case ElementType.MVar:
case ElementType.Var: {
var generic_parameter = (GenericParameter) type;
WriteElementType (etype);
var position = generic_parameter.Position;
if (position == -1)
throw new NotSupportedException ();
WriteCompressedUInt32 ((uint) position);
break;
}
case ElementType.GenericInst: {
var generic_instance = (GenericInstanceType) type;
WriteElementType (ElementType.GenericInst);
WriteElementType (generic_instance.IsValueType ? ElementType.ValueType : ElementType.Class);
WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (generic_instance.ElementType));
WriteGenericInstanceSignature (generic_instance);
break;
}
case ElementType.Ptr:
case ElementType.ByRef:
case ElementType.Pinned:
case ElementType.Sentinel: {
var type_spec = (TypeSpecification) type;
WriteElementType (etype);
WriteTypeSignature (type_spec.ElementType);
break;
}
case ElementType.FnPtr: {
var fptr = (FunctionPointerType) type;
WriteElementType (ElementType.FnPtr);
WriteMethodSignature (fptr);
break;
}
case ElementType.CModOpt:
case ElementType.CModReqD: {
var modifier = (IModifierType) type;
WriteModifierSignature (etype, modifier);
break;
}
case ElementType.Array: {
var array = (ArrayType) type;
if (!array.IsVector) {
WriteArrayTypeSignature (array);
break;
}
WriteElementType (ElementType.SzArray);
WriteTypeSignature (array.ElementType);
break;
}
case ElementType.None: {
WriteElementType (type.IsValueType ? ElementType.ValueType : ElementType.Class);
WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type));
break;
}
default:
if (!TryWriteElementType (type))
throw new NotSupportedException ();
break;
}
}
void WriteArrayTypeSignature (ArrayType array)
{
WriteElementType (ElementType.Array);
WriteTypeSignature (array.ElementType);
var dimensions = array.Dimensions;
var rank = dimensions.Count;
WriteCompressedUInt32 ((uint) rank);
var sized = 0;
var lbounds = 0;
for (int i = 0; i < rank; i++) {
var dimension = dimensions [i];
if (dimension.UpperBound.HasValue) {
sized++;
lbounds++;
} else if (dimension.LowerBound.HasValue)
lbounds++;
}
var sizes = new int [sized];
var low_bounds = new int [lbounds];
for (int i = 0; i < lbounds; i++) {
var dimension = dimensions [i];
low_bounds [i] = dimension.LowerBound.GetValueOrDefault ();
if (dimension.UpperBound.HasValue)
sizes [i] = dimension.UpperBound.Value - low_bounds [i] + 1;
}
WriteCompressedUInt32 ((uint) sized);
for (int i = 0; i < sized; i++)
WriteCompressedUInt32 ((uint) sizes [i]);
WriteCompressedUInt32 ((uint) lbounds);
for (int i = 0; i < lbounds; i++)
WriteCompressedInt32 (low_bounds [i]);
}
public void WriteGenericInstanceSignature (IGenericInstance instance)
{
var generic_arguments = instance.GenericArguments;
var arity = generic_arguments.Count;
WriteCompressedUInt32 ((uint) arity);
for (int i = 0; i < arity; i++)
WriteTypeSignature (generic_arguments [i]);
}
void WriteModifierSignature (ElementType element_type, IModifierType type)
{
WriteElementType (element_type);
WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type.ModifierType));
WriteTypeSignature (type.ElementType);
}
bool TryWriteElementType (TypeReference type)
{
var element = type.etype;
if (element == ElementType.None)
return false;
WriteElementType (element);
return true;
}
public void WriteConstantString (string value)
{
if (value != null)
WriteBytes (Encoding.Unicode.GetBytes (value));
else
WriteByte (0xff);
}
public void WriteConstantPrimitive (object value)
{
WritePrimitiveValue (value);
}
public void WriteCustomAttributeConstructorArguments (CustomAttribute attribute)
{
if (!attribute.HasConstructorArguments)
return;
var arguments = attribute.ConstructorArguments;
var parameters = attribute.Constructor.Parameters;
if (parameters.Count != arguments.Count)
throw new InvalidOperationException ();
for (int i = 0; i < arguments.Count; i++)
WriteCustomAttributeFixedArgument (parameters [i].ParameterType, arguments [i]);
}
void WriteCustomAttributeFixedArgument (TypeReference type, CustomAttributeArgument argument)
{
if (type.IsArray) {
WriteCustomAttributeFixedArrayArgument ((ArrayType) type, argument);
return;
}
WriteCustomAttributeElement (type, argument);
}
void WriteCustomAttributeFixedArrayArgument (ArrayType type, CustomAttributeArgument argument)
{
var values = argument.Value as CustomAttributeArgument [];
if (values == null) {
WriteUInt32 (0xffffffff);
return;
}
WriteInt32 (values.Length);
if (values.Length == 0)
return;
var element_type = type.ElementType;
for (int i = 0; i < values.Length; i++)
WriteCustomAttributeElement (element_type, values [i]);
}
void WriteCustomAttributeElement (TypeReference type, CustomAttributeArgument argument)
{
if (type.IsArray) {
WriteCustomAttributeFixedArrayArgument ((ArrayType) type, argument);
return;
}
if (type.etype == ElementType.Object) {
argument = (CustomAttributeArgument) argument.Value;
type = argument.Type;
WriteCustomAttributeFieldOrPropType (type);
WriteCustomAttributeElement (type, argument);
return;
}
WriteCustomAttributeValue (type, argument.Value);
}
void WriteCustomAttributeValue (TypeReference type, object value)
{
var etype = type.etype;
switch (etype) {
case ElementType.String:
var @string = (string) value;
if (@string == null)
WriteByte (0xff);
else
WriteUTF8String (@string);
break;
case ElementType.None:
if (type.IsTypeOf ("System", "Type"))
WriteTypeReference ((TypeReference) value);
else
WriteCustomAttributeEnumValue (type, value);
break;
default:
WritePrimitiveValue (value);
break;
}
}
void WritePrimitiveValue (object value)
{
if (value == null)
throw new ArgumentNullException ();
switch (value.GetType ().GetTypeCode ()) {
case TypeCode.Boolean:
WriteByte ((byte) (((bool) value) ? 1 : 0));
break;
case TypeCode.Byte:
WriteByte ((byte) value);
break;
case TypeCode.SByte:
WriteSByte ((sbyte) value);
break;
case TypeCode.Int16:
WriteInt16 ((short) value);
break;
case TypeCode.UInt16:
WriteUInt16 ((ushort) value);
break;
case TypeCode.Char:
WriteInt16 ((short) (char) value);
break;
case TypeCode.Int32:
WriteInt32 ((int) value);
break;
case TypeCode.UInt32:
WriteUInt32 ((uint) value);
break;
case TypeCode.Single:
WriteSingle ((float) value);
break;
case TypeCode.Int64:
WriteInt64 ((long) value);
break;
case TypeCode.UInt64:
WriteUInt64 ((ulong) value);
break;
case TypeCode.Double:
WriteDouble ((double) value);
break;
default:
throw new NotSupportedException (value.GetType ().FullName);
}
}
void WriteCustomAttributeEnumValue (TypeReference enum_type, object value)
{
var type = enum_type.CheckedResolve ();
if (!type.IsEnum)
throw new ArgumentException ();
WriteCustomAttributeValue (type.GetEnumUnderlyingType (), value);
}
void WriteCustomAttributeFieldOrPropType (TypeReference type)
{
if (type.IsArray) {
var array = (ArrayType) type;
WriteElementType (ElementType.SzArray);
WriteCustomAttributeFieldOrPropType (array.ElementType);
return;
}
var etype = type.etype;
switch (etype) {
case ElementType.Object:
WriteElementType (ElementType.Boxed);
return;
case ElementType.None:
if (type.IsTypeOf ("System", "Type"))
WriteElementType (ElementType.Type);
else {
WriteElementType (ElementType.Enum);
WriteTypeReference (type);
}
return;
default:
WriteElementType (etype);
return;
}
}
public void WriteCustomAttributeNamedArguments (CustomAttribute attribute)
{
var count = GetNamedArgumentCount (attribute);
WriteUInt16 ((ushort) count);
if (count == 0)
return;
WriteICustomAttributeNamedArguments (attribute);
}
static int GetNamedArgumentCount (ICustomAttribute attribute)
{
int count = 0;
if (attribute.HasFields)
count += attribute.Fields.Count;
if (attribute.HasProperties)
count += attribute.Properties.Count;
return count;
}
void WriteICustomAttributeNamedArguments (ICustomAttribute attribute)
{
if (attribute.HasFields)
WriteCustomAttributeNamedArguments (0x53, attribute.Fields);
if (attribute.HasProperties)
WriteCustomAttributeNamedArguments (0x54, attribute.Properties);
}
void WriteCustomAttributeNamedArguments (byte kind, Collection<CustomAttributeNamedArgument> named_arguments)
{
for (int i = 0; i < named_arguments.Count; i++)
WriteCustomAttributeNamedArgument (kind, named_arguments [i]);
}
void WriteCustomAttributeNamedArgument (byte kind, CustomAttributeNamedArgument named_argument)
{
var argument = named_argument.Argument;
WriteByte (kind);
WriteCustomAttributeFieldOrPropType (argument.Type);
WriteUTF8String (named_argument.Name);
WriteCustomAttributeFixedArgument (argument.Type, argument);
}
void WriteSecurityAttribute (SecurityAttribute attribute)
{
WriteTypeReference (attribute.AttributeType);
var count = GetNamedArgumentCount (attribute);
if (count == 0) {
WriteCompressedUInt32 (1); // length
WriteCompressedUInt32 (0); // count
return;
}
var buffer = new SignatureWriter (metadata);
buffer.WriteCompressedUInt32 ((uint) count);
buffer.WriteICustomAttributeNamedArguments (attribute);
WriteCompressedUInt32 ((uint) buffer.length);
WriteBytes (buffer);
}
public void WriteSecurityDeclaration (SecurityDeclaration declaration)
{
WriteByte ((byte) '.');
var attributes = declaration.security_attributes;
if (attributes == null)
throw new NotSupportedException ();
WriteCompressedUInt32 ((uint) attributes.Count);
for (int i = 0; i < attributes.Count; i++)
WriteSecurityAttribute (attributes [i]);
}
public void WriteXmlSecurityDeclaration (SecurityDeclaration declaration)
{
var xml = GetXmlSecurityDeclaration (declaration);
if (xml == null)
throw new NotSupportedException ();
WriteBytes (Encoding.Unicode.GetBytes (xml));
}
static string GetXmlSecurityDeclaration (SecurityDeclaration declaration)
{
if (declaration.security_attributes == null || declaration.security_attributes.Count != 1)
return null;
var attribute = declaration.security_attributes [0];
if (!attribute.AttributeType.IsTypeOf ("System.Security.Permissions", "PermissionSetAttribute"))
return null;
if (attribute.properties == null || attribute.properties.Count != 1)
return null;
var property = attribute.properties [0];
if (property.Name != "XML")
return null;
return (string) property.Argument.Value;
}
void WriteTypeReference (TypeReference type)
{
WriteUTF8String (TypeParser.ToParseable (type, top_level: false));
}
public void WriteMarshalInfo (MarshalInfo marshal_info)
{
WriteNativeType (marshal_info.native);
switch (marshal_info.native) {
case NativeType.Array: {
var array = (ArrayMarshalInfo) marshal_info;
if (array.element_type != NativeType.None)
WriteNativeType (array.element_type);
if (array.size_parameter_index > -1)
WriteCompressedUInt32 ((uint) array.size_parameter_index);
if (array.size > -1)
WriteCompressedUInt32 ((uint) array.size);
if (array.size_parameter_multiplier > -1)
WriteCompressedUInt32 ((uint) array.size_parameter_multiplier);
return;
}
case NativeType.SafeArray: {
var array = (SafeArrayMarshalInfo) marshal_info;
if (array.element_type != VariantType.None)
WriteVariantType (array.element_type);
return;
}
case NativeType.FixedArray: {
var array = (FixedArrayMarshalInfo) marshal_info;
if (array.size > -1)
WriteCompressedUInt32 ((uint) array.size);
if (array.element_type != NativeType.None)
WriteNativeType (array.element_type);
return;
}
case NativeType.FixedSysString:
var sys_string = (FixedSysStringMarshalInfo) marshal_info;
if (sys_string.size > -1)
WriteCompressedUInt32 ((uint) sys_string.size);
return;
case NativeType.CustomMarshaler:
var marshaler = (CustomMarshalInfo) marshal_info;
WriteUTF8String (marshaler.guid != Guid.Empty ? marshaler.guid.ToString () : string.Empty);
WriteUTF8String (marshaler.unmanaged_type);
WriteTypeReference (marshaler.managed_type);
WriteUTF8String (marshaler.cookie);
return;
}
}
void WriteNativeType (NativeType native)
{
WriteByte ((byte) native);
}
void WriteVariantType (VariantType variant)
{
WriteByte ((byte) variant);
}
public void WriteSequencePoints (MethodDebugInformation info)
{
var start_line = -1;
var start_column = -1;
WriteCompressedUInt32 (info.local_var_token.RID);
Document previous_document;
if (!info.TryGetUniqueDocument (out previous_document))
previous_document = null;
for (int i = 0; i < info.SequencePoints.Count; i++) {
var sequence_point = info.SequencePoints [i];
var document = sequence_point.Document;
if (previous_document != document) {
var document_token = metadata.GetDocumentToken (document);
if (previous_document != null)
WriteCompressedUInt32 (0);
WriteCompressedUInt32 (document_token.RID);
previous_document = document;
}
if (i > 0)
WriteCompressedUInt32 ((uint) (sequence_point.Offset - info.SequencePoints [i - 1].Offset));
else
WriteCompressedUInt32 ((uint) sequence_point.Offset);
if (sequence_point.IsHidden) {
WriteInt16 (0);
continue;
}
var delta_lines = sequence_point.EndLine - sequence_point.StartLine;
var delta_columns = sequence_point.EndColumn - sequence_point.StartColumn;
WriteCompressedUInt32 ((uint) delta_lines);
if (delta_lines == 0)
WriteCompressedUInt32((uint) delta_columns);
else
WriteCompressedInt32 (delta_columns);
if (start_line < 0) {
WriteCompressedUInt32 ((uint) sequence_point.StartLine);
WriteCompressedUInt32 ((uint) sequence_point.StartColumn);
} else {
WriteCompressedInt32 (sequence_point.StartLine - start_line);
WriteCompressedInt32 (sequence_point.StartColumn - start_column);
}
start_line = sequence_point.StartLine;
start_column = sequence_point.StartColumn;
}
}
}
#endif
static partial class Mixin {
public static bool TryGetUniqueDocument (this MethodDebugInformation info, out Document document)
{
document = info.SequencePoints [0].Document;
for (int i = 1; i < info.SequencePoints.Count; i++) {
var sequence_point = info.SequencePoints [i];
if (sequence_point.Document != document)
return false;
}
return true;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal delegate AssemblyDefinition AssemblyResolveEventHandler (object sender, AssemblyNameReference reference);
internal sealed class AssemblyResolveEventArgs : EventArgs {
readonly AssemblyNameReference reference;
public AssemblyNameReference AssemblyReference {
get { return reference; }
}
public AssemblyResolveEventArgs (AssemblyNameReference reference)
{
this.reference = reference;
}
}
#if !NET_CORE
[Serializable]
#endif
internal sealed class AssemblyResolutionException : FileNotFoundException {
readonly AssemblyNameReference reference;
public AssemblyNameReference AssemblyReference {
get { return reference; }
}
public AssemblyResolutionException (AssemblyNameReference reference)
: this (reference, null)
{
}
public AssemblyResolutionException (AssemblyNameReference reference, Exception innerException)
: base (string.Format ("Failed to resolve assembly: '{0}'", reference), innerException)
{
this.reference = reference;
}
#if !NET_CORE
AssemblyResolutionException (
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base (info, context)
{
}
#endif
}
internal abstract class BaseAssemblyResolver : IAssemblyResolver {
static readonly bool on_mono = Type.GetType ("Mono.Runtime") != null;
readonly Collection<string> directories;
#if NET_CORE
// Maps file names of available trusted platform assemblies to their full paths.
// Internal for testing.
internal static readonly Lazy<Dictionary<string, string>> TrustedPlatformAssemblies = new Lazy<Dictionary<string, string>> (CreateTrustedPlatformAssemblyMap);
#else
Collection<string> gac_paths;
#endif
public void AddSearchDirectory (string directory)
{
directories.Add (directory);
}
public void RemoveSearchDirectory (string directory)
{
directories.Remove (directory);
}
public string [] GetSearchDirectories ()
{
var directories = new string [this.directories.size];
Array.Copy (this.directories.items, directories, directories.Length);
return directories;
}
public event AssemblyResolveEventHandler ResolveFailure;
protected BaseAssemblyResolver ()
{
directories = new Collection<string> (2) { ".", "bin" };
}
AssemblyDefinition GetAssembly (string file, ReaderParameters parameters)
{
if (parameters.AssemblyResolver == null)
parameters.AssemblyResolver = this;
return ModuleDefinition.ReadModule (file, parameters).Assembly;
}
public virtual AssemblyDefinition Resolve (AssemblyNameReference name)
{
return Resolve (name, new ReaderParameters ());
}
public virtual AssemblyDefinition Resolve (AssemblyNameReference name, ReaderParameters parameters)
{
Mixin.CheckName (name);
Mixin.CheckParameters (parameters);
var assembly = SearchDirectory (name, directories, parameters);
if (assembly != null)
return assembly;
if (name.IsRetargetable) {
// if the reference is retargetable, zero it
name = new AssemblyNameReference (name.Name, Mixin.ZeroVersion) {
PublicKeyToken = Empty<byte>.Array,
};
}
#if NET_CORE
assembly = SearchTrustedPlatformAssemblies (name, parameters);
if (assembly != null)
return assembly;
#else
var framework_dir = Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName);
var framework_dirs = on_mono
? new [] { framework_dir, Path.Combine (framework_dir, "Facades") }
: new [] { framework_dir };
if (IsZero (name.Version)) {
assembly = SearchDirectory (name, framework_dirs, parameters);
if (assembly != null)
return assembly;
}
if (name.Name == "mscorlib") {
assembly = GetCorlib (name, parameters);
if (assembly != null)
return assembly;
}
assembly = GetAssemblyInGac (name, parameters);
if (assembly != null)
return assembly;
assembly = SearchDirectory (name, framework_dirs, parameters);
if (assembly != null)
return assembly;
#endif
if (ResolveFailure != null) {
assembly = ResolveFailure (this, name);
if (assembly != null)
return assembly;
}
throw new AssemblyResolutionException (name);
}
#if NET_CORE
AssemblyDefinition SearchTrustedPlatformAssemblies (AssemblyNameReference name, ReaderParameters parameters)
{
if (name.IsWindowsRuntime)
return null;
if (TrustedPlatformAssemblies.Value.TryGetValue (name.Name, out string path))
return GetAssembly (path, parameters);
return null;
}
static Dictionary<string, string> CreateTrustedPlatformAssemblyMap ()
{
var result = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase);
string paths;
try {
// AppContext is only available on platforms that implement .NET Standard 1.6
var appContextType = Type.GetType ("System.AppContext, System.AppContext, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
var getData = appContextType?.GetTypeInfo ().GetDeclaredMethod ("GetData");
paths = (string) getData?.Invoke (null, new [] { "TRUSTED_PLATFORM_ASSEMBLIES" });
} catch {
paths = null;
}
if (paths == null)
return result;
foreach (var path in paths.Split (Path.PathSeparator))
if (string.Equals (Path.GetExtension (path), ".dll", StringComparison.OrdinalIgnoreCase))
result [Path.GetFileNameWithoutExtension (path)] = path;
return result;
}
#endif
protected virtual AssemblyDefinition SearchDirectory (AssemblyNameReference name, IEnumerable<string> directories, ReaderParameters parameters)
{
var extensions = name.IsWindowsRuntime ? new [] { ".winmd", ".dll" } : new [] { ".exe", ".dll" };
foreach (var directory in directories) {
foreach (var extension in extensions) {
string file = Path.Combine (directory, name.Name + extension);
if (!File.Exists (file))
continue;
try {
return GetAssembly (file, parameters);
} catch (System.BadImageFormatException) {
continue;
}
}
}
return null;
}
static bool IsZero (Version version)
{
return version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0;
}
#if !NET_CORE
AssemblyDefinition GetCorlib (AssemblyNameReference reference, ReaderParameters parameters)
{
var version = reference.Version;
var corlib = typeof (object).Assembly.GetName ();
if (corlib.Version == version || IsZero (version))
return GetAssembly (typeof (object).Module.FullyQualifiedName, parameters);
var path = Directory.GetParent (
Directory.GetParent (
typeof (object).Module.FullyQualifiedName).FullName
).FullName;
if (on_mono) {
if (version.Major == 1)
path = Path.Combine (path, "1.0");
else if (version.Major == 2) {
if (version.MajorRevision == 5)
path = Path.Combine (path, "2.1");
else
path = Path.Combine (path, "2.0");
} else if (version.Major == 4)
path = Path.Combine (path, "4.0");
else
throw new NotSupportedException ("Version not supported: " + version);
} else {
switch (version.Major) {
case 1:
if (version.MajorRevision == 3300)
path = Path.Combine (path, "v1.0.3705");
else
path = Path.Combine (path, "v1.0.5000.0");
break;
case 2:
path = Path.Combine (path, "v2.0.50727");
break;
case 4:
path = Path.Combine (path, "v4.0.30319");
break;
default:
throw new NotSupportedException ("Version not supported: " + version);
}
}
var file = Path.Combine (path, "mscorlib.dll");
if (File.Exists (file))
return GetAssembly (file, parameters);
if (on_mono && Directory.Exists (path + "-api")) {
file = Path.Combine (path + "-api", "mscorlib.dll");
if (File.Exists (file))
return GetAssembly (file, parameters);
}
return null;
}
static Collection<string> GetGacPaths ()
{
if (on_mono)
return GetDefaultMonoGacPaths ();
var paths = new Collection<string> (2);
var windir = Environment.GetEnvironmentVariable ("WINDIR");
if (windir == null)
return paths;
paths.Add (Path.Combine (windir, "assembly"));
paths.Add (Path.Combine (windir, Path.Combine ("Microsoft.NET", "assembly")));
return paths;
}
static Collection<string> GetDefaultMonoGacPaths ()
{
var paths = new Collection<string> (1);
var gac = GetCurrentMonoGac ();
if (gac != null)
paths.Add (gac);
var gac_paths_env = Environment.GetEnvironmentVariable ("MONO_GAC_PREFIX");
if (string.IsNullOrEmpty (gac_paths_env))
return paths;
var prefixes = gac_paths_env.Split (Path.PathSeparator);
foreach (var prefix in prefixes) {
if (string.IsNullOrEmpty (prefix))
continue;
var gac_path = Path.Combine (Path.Combine (Path.Combine (prefix, "lib"), "mono"), "gac");
if (Directory.Exists (gac_path) && !paths.Contains (gac))
paths.Add (gac_path);
}
return paths;
}
static string GetCurrentMonoGac ()
{
return Path.Combine (
Directory.GetParent (
Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName)).FullName,
"gac");
}
AssemblyDefinition GetAssemblyInGac (AssemblyNameReference reference, ReaderParameters parameters)
{
if (reference.PublicKeyToken == null || reference.PublicKeyToken.Length == 0)
return null;
if (gac_paths == null)
gac_paths = GetGacPaths ();
if (on_mono)
return GetAssemblyInMonoGac (reference, parameters);
return GetAssemblyInNetGac (reference, parameters);
}
AssemblyDefinition GetAssemblyInMonoGac (AssemblyNameReference reference, ReaderParameters parameters)
{
for (int i = 0; i < gac_paths.Count; i++) {
var gac_path = gac_paths [i];
var file = GetAssemblyFile (reference, string.Empty, gac_path);
if (File.Exists (file))
return GetAssembly (file, parameters);
}
return null;
}
AssemblyDefinition GetAssemblyInNetGac (AssemblyNameReference reference, ReaderParameters parameters)
{
var gacs = new [] { "GAC_MSIL", "GAC_32", "GAC_64", "GAC" };
var prefixes = new [] { string.Empty, "v4.0_" };
for (int i = 0; i < 2; i++) {
for (int j = 0; j < gacs.Length; j++) {
var gac = Path.Combine (gac_paths [i], gacs [j]);
var file = GetAssemblyFile (reference, prefixes [i], gac);
if (Directory.Exists (gac) && File.Exists (file))
return GetAssembly (file, parameters);
}
}
return null;
}
#endif
static string GetAssemblyFile (AssemblyNameReference reference, string prefix, string gac)
{
var gac_folder = new StringBuilder ()
.Append (prefix)
.Append (reference.Version)
.Append ("__");
for (int i = 0; i < reference.PublicKeyToken.Length; i++)
gac_folder.Append (reference.PublicKeyToken [i].ToString ("x2"));
return Path.Combine (
Path.Combine (
Path.Combine (gac, reference.Name), gac_folder.ToString ()),
reference.Name + ".dll");
}
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
protected virtual void Dispose (bool disposing)
{
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Text;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal sealed class CallSite : IMethodSignature {
readonly MethodReference signature;
public bool HasThis {
get { return signature.HasThis; }
set { signature.HasThis = value; }
}
public bool ExplicitThis {
get { return signature.ExplicitThis; }
set { signature.ExplicitThis = value; }
}
public MethodCallingConvention CallingConvention {
get { return signature.CallingConvention; }
set { signature.CallingConvention = value; }
}
public bool HasParameters {
get { return signature.HasParameters; }
}
public Collection<ParameterDefinition> Parameters {
get { return signature.Parameters; }
}
public TypeReference ReturnType {
get { return signature.MethodReturnType.ReturnType; }
set { signature.MethodReturnType.ReturnType = value; }
}
public MethodReturnType MethodReturnType {
get { return signature.MethodReturnType; }
}
public string Name {
get { return string.Empty; }
set { throw new InvalidOperationException (); }
}
public string Namespace {
get { return string.Empty; }
set { throw new InvalidOperationException (); }
}
public ModuleDefinition Module {
get { return ReturnType.Module; }
}
public IMetadataScope Scope {
get { return signature.ReturnType.Scope; }
}
public MetadataToken MetadataToken {
get { return signature.token; }
set { signature.token = value; }
}
public string FullName {
get {
var signature = new StringBuilder ();
signature.Append (ReturnType.FullName);
this.MethodSignatureFullName (signature);
return signature.ToString ();
}
}
internal CallSite ()
{
this.signature = new MethodReference ();
this.signature.token = new MetadataToken (TokenType.Signature, 0);
}
public CallSite (TypeReference returnType)
: this ()
{
if (returnType == null)
throw new ArgumentNullException ("returnType");
this.signature.ReturnType = returnType;
}
public override string ToString ()
{
return FullName;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
static class Consts
{
public const string AssemblyName = "Mono.Cecil";
public const string PublicKey = "00240000048000009400000006020000002400005253413100040000010001002b5c9f7f04346c324a3176f8d3ee823bbf2d60efdbc35f86fd9e65ea3e6cd11bcdcba3a353e55133c8ac5c4caaba581b2c6dfff2cc2d0edc43959ddb86b973300a479a82419ef489c3225f1fe429a708507bd515835160e10bc743d20ca33ab9570cfd68d479fcf0bc797a763bec5d1000f0159ef619e709d915975e87beebaf";
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Diagnostics;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal struct CustomAttributeArgument {
readonly TypeReference type;
readonly object value;
public TypeReference Type {
get { return type; }
}
public object Value {
get { return value; }
}
public CustomAttributeArgument (TypeReference type, object value)
{
Mixin.CheckType (type);
this.type = type;
this.value = value;
}
}
internal struct CustomAttributeNamedArgument {
readonly string name;
readonly CustomAttributeArgument argument;
public string Name {
get { return name; }
}
public CustomAttributeArgument Argument {
get { return argument; }
}
public CustomAttributeNamedArgument (string name, CustomAttributeArgument argument)
{
Mixin.CheckName (name);
this.name = name;
this.argument = argument;
}
}
internal interface ICustomAttribute {
TypeReference AttributeType { get; }
bool HasFields { get; }
bool HasProperties { get; }
bool HasConstructorArguments { get; }
Collection<CustomAttributeNamedArgument> Fields { get; }
Collection<CustomAttributeNamedArgument> Properties { get; }
Collection<CustomAttributeArgument> ConstructorArguments { get; }
}
[DebuggerDisplay ("{AttributeType}")]
internal sealed class CustomAttribute : ICustomAttribute {
internal CustomAttributeValueProjection projection;
readonly internal uint signature;
internal bool resolved;
MethodReference constructor;
byte [] blob;
internal Collection<CustomAttributeArgument> arguments;
internal Collection<CustomAttributeNamedArgument> fields;
internal Collection<CustomAttributeNamedArgument> properties;
public MethodReference Constructor {
get { return constructor; }
set { constructor = value; }
}
public TypeReference AttributeType {
get { return constructor.DeclaringType; }
}
public bool IsResolved {
get { return resolved; }
}
public bool HasConstructorArguments {
get {
Resolve ();
return !arguments.IsNullOrEmpty ();
}
}
public Collection<CustomAttributeArgument> ConstructorArguments {
get {
Resolve ();
return arguments ?? (arguments = new Collection<CustomAttributeArgument> ());
}
}
public bool HasFields {
get {
Resolve ();
return !fields.IsNullOrEmpty ();
}
}
public Collection<CustomAttributeNamedArgument> Fields {
get {
Resolve ();
return fields ?? (fields = new Collection<CustomAttributeNamedArgument> ());
}
}
public bool HasProperties {
get {
Resolve ();
return !properties.IsNullOrEmpty ();
}
}
public Collection<CustomAttributeNamedArgument> Properties {
get {
Resolve ();
return properties ?? (properties = new Collection<CustomAttributeNamedArgument> ());
}
}
internal bool HasImage {
get { return constructor != null && constructor.HasImage; }
}
internal ModuleDefinition Module {
get { return constructor.Module; }
}
internal CustomAttribute (uint signature, MethodReference constructor)
{
this.signature = signature;
this.constructor = constructor;
this.resolved = false;
}
public CustomAttribute (MethodReference constructor)
{
this.constructor = constructor;
this.resolved = true;
}
public CustomAttribute (MethodReference constructor, byte [] blob)
{
this.constructor = constructor;
this.resolved = false;
this.blob = blob;
}
public byte [] GetBlob ()
{
if (blob != null)
return blob;
if (!HasImage)
throw new NotSupportedException ();
return Module.Read (ref blob, this, (attribute, reader) => reader.ReadCustomAttributeBlob (attribute.signature));
}
void Resolve ()
{
if (resolved || !HasImage)
return;
Module.Read (this, (attribute, reader) => {
try {
reader.ReadCustomAttributeSignature (attribute);
resolved = true;
} catch (ResolutionException) {
if (arguments != null)
arguments.Clear ();
if (fields != null)
fields.Clear ();
if (properties != null)
properties.Clear ();
resolved = false;
}
});
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Collections.Generic;
namespace Mono.Cecil {
internal class DefaultAssemblyResolver : BaseAssemblyResolver {
readonly IDictionary<string, AssemblyDefinition> cache;
public DefaultAssemblyResolver ()
{
cache = new Dictionary<string, AssemblyDefinition> (StringComparer.Ordinal);
}
public override AssemblyDefinition Resolve (AssemblyNameReference name)
{
Mixin.CheckName (name);
AssemblyDefinition assembly;
if (cache.TryGetValue (name.FullName, out assembly))
return assembly;
assembly = base.Resolve (name);
cache [name.FullName] = assembly;
return assembly;
}
protected void RegisterAssembly (AssemblyDefinition assembly)
{
if (assembly == null)
throw new ArgumentNullException ("assembly");
var name = assembly.Name.FullName;
if (cache.ContainsKey (name))
return;
cache [name] = assembly;
}
protected override void Dispose (bool disposing)
{
foreach (var assembly in cache.Values)
assembly.Dispose ();
cache.Clear ();
base.Dispose (disposing);
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.IO;
namespace Mono.Cecil {
internal sealed class EmbeddedResource : Resource {
readonly MetadataReader reader;
uint? offset;
byte [] data;
Stream stream;
public override ResourceType ResourceType {
get { return ResourceType.Embedded; }
}
public EmbeddedResource (string name, ManifestResourceAttributes attributes, byte [] data) :
base (name, attributes)
{
this.data = data;
}
public EmbeddedResource (string name, ManifestResourceAttributes attributes, Stream stream) :
base (name, attributes)
{
this.stream = stream;
}
internal EmbeddedResource (string name, ManifestResourceAttributes attributes, uint offset, MetadataReader reader)
: base (name, attributes)
{
this.offset = offset;
this.reader = reader;
}
public Stream GetResourceStream ()
{
if (stream != null)
return stream;
if (data != null)
return new MemoryStream (data);
if (offset.HasValue)
return new MemoryStream (reader.GetManagedResource (offset.Value));
throw new InvalidOperationException ();
}
public byte [] GetResourceData ()
{
if (stream != null)
return ReadStream (stream);
if (data != null)
return data;
if (offset.HasValue)
return reader.GetManagedResource (offset.Value);
throw new InvalidOperationException ();
}
static byte [] ReadStream (Stream stream)
{
int read;
if (stream.CanSeek) {
var length = (int) stream.Length;
var data = new byte [length];
int offset = 0;
while ((read = stream.Read (data, offset, length - offset)) > 0)
offset += read;
return data;
}
var buffer = new byte [1024 * 8];
var memory = new MemoryStream ();
while ((read = stream.Read (buffer, 0, buffer.Length)) > 0)
memory.Write (buffer, 0, read);
return memory.ToArray ();
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
[Flags]
internal enum EventAttributes : ushort {
None = 0x0000,
SpecialName = 0x0200, // Event is special
RTSpecialName = 0x0400 // CLI provides 'special' behavior, depending upon the name of the event
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal sealed class EventDefinition : EventReference, IMemberDefinition {
ushort attributes;
Collection<CustomAttribute> custom_attributes;
internal MethodDefinition add_method;
internal MethodDefinition invoke_method;
internal MethodDefinition remove_method;
internal Collection<MethodDefinition> other_methods;
public EventAttributes Attributes {
get { return (EventAttributes) attributes; }
set { attributes = (ushort) value; }
}
public MethodDefinition AddMethod {
get {
if (add_method != null)
return add_method;
InitializeMethods ();
return add_method;
}
set { add_method = value; }
}
public MethodDefinition InvokeMethod {
get {
if (invoke_method != null)
return invoke_method;
InitializeMethods ();
return invoke_method;
}
set { invoke_method = value; }
}
public MethodDefinition RemoveMethod {
get {
if (remove_method != null)
return remove_method;
InitializeMethods ();
return remove_method;
}
set { remove_method = value; }
}
public bool HasOtherMethods {
get {
if (other_methods != null)
return other_methods.Count > 0;
InitializeMethods ();
return !other_methods.IsNullOrEmpty ();
}
}
public Collection<MethodDefinition> OtherMethods {
get {
if (other_methods != null)
return other_methods;
InitializeMethods ();
if (other_methods != null)
return other_methods;
return other_methods = new Collection<MethodDefinition> ();
}
}
public bool HasCustomAttributes {
get {
if (custom_attributes != null)
return custom_attributes.Count > 0;
return this.GetHasCustomAttributes (Module);
}
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); }
}
#region EventAttributes
public bool IsSpecialName {
get { return attributes.GetAttributes ((ushort) EventAttributes.SpecialName); }
set { attributes = attributes.SetAttributes ((ushort) EventAttributes.SpecialName, value); }
}
public bool IsRuntimeSpecialName {
get { return attributes.GetAttributes ((ushort) EventAttributes.RTSpecialName); }
set { attributes = attributes.SetAttributes ((ushort) EventAttributes.RTSpecialName, value); }
}
#endregion
public new TypeDefinition DeclaringType {
get { return (TypeDefinition) base.DeclaringType; }
set { base.DeclaringType = value; }
}
public override bool IsDefinition {
get { return true; }
}
public EventDefinition (string name, EventAttributes attributes, TypeReference eventType)
: base (name, eventType)
{
this.attributes = (ushort) attributes;
this.token = new MetadataToken (TokenType.Event);
}
void InitializeMethods ()
{
var module = this.Module;
if (module == null)
return;
lock (module.SyncRoot) {
if (add_method != null
|| invoke_method != null
|| remove_method != null)
return;
if (!module.HasImage ())
return;
module.Read (this, (@event, reader) => reader.ReadMethods (@event));
}
}
public override EventDefinition Resolve ()
{
return this;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
internal abstract class EventReference : MemberReference {
TypeReference event_type;
public TypeReference EventType {
get { return event_type; }
set { event_type = value; }
}
public override string FullName {
get { return event_type.FullName + " " + MemberFullName (); }
}
protected EventReference (string name, TypeReference eventType)
: base (name)
{
Mixin.CheckType (eventType, Mixin.Argument.eventType);
event_type = eventType;
}
protected override IMemberDefinition ResolveDefinition ()
{
return this.Resolve ();
}
public new abstract EventDefinition Resolve ();
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
internal sealed class ExportedType : IMetadataTokenProvider {
string @namespace;
string name;
uint attributes;
IMetadataScope scope;
ModuleDefinition module;
int identifier;
ExportedType declaring_type;
internal MetadataToken token;
public string Namespace {
get { return @namespace; }
set { @namespace = value; }
}
public string Name {
get { return name; }
set { name = value; }
}
public TypeAttributes Attributes {
get { return (TypeAttributes) attributes; }
set { attributes = (uint) value; }
}
public IMetadataScope Scope {
get {
if (declaring_type != null)
return declaring_type.Scope;
return scope;
}
set {
if (declaring_type != null) {
declaring_type.Scope = value;
return;
}
scope = value;
}
}
public ExportedType DeclaringType {
get { return declaring_type; }
set { declaring_type = value; }
}
public MetadataToken MetadataToken {
get { return token; }
set { token = value; }
}
public int Identifier {
get { return identifier; }
set { identifier = value; }
}
#region TypeAttributes
public bool IsNotPublic {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic, value); }
}
public bool IsPublic {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public, value); }
}
public bool IsNestedPublic {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic, value); }
}
public bool IsNestedPrivate {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate, value); }
}
public bool IsNestedFamily {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily, value); }
}
public bool IsNestedAssembly {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly, value); }
}
public bool IsNestedFamilyAndAssembly {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem, value); }
}
public bool IsNestedFamilyOrAssembly {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem, value); }
}
public bool IsAutoLayout {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout, value); }
}
public bool IsSequentialLayout {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout, value); }
}
public bool IsExplicitLayout {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout, value); }
}
public bool IsClass {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class, value); }
}
public bool IsInterface {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface, value); }
}
public bool IsAbstract {
get { return attributes.GetAttributes ((uint) TypeAttributes.Abstract); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Abstract, value); }
}
public bool IsSealed {
get { return attributes.GetAttributes ((uint) TypeAttributes.Sealed); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Sealed, value); }
}
public bool IsSpecialName {
get { return attributes.GetAttributes ((uint) TypeAttributes.SpecialName); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.SpecialName, value); }
}
public bool IsImport {
get { return attributes.GetAttributes ((uint) TypeAttributes.Import); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Import, value); }
}
public bool IsSerializable {
get { return attributes.GetAttributes ((uint) TypeAttributes.Serializable); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Serializable, value); }
}
public bool IsAnsiClass {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass, value); }
}
public bool IsUnicodeClass {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass, value); }
}
public bool IsAutoClass {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass, value); }
}
public bool IsBeforeFieldInit {
get { return attributes.GetAttributes ((uint) TypeAttributes.BeforeFieldInit); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.BeforeFieldInit, value); }
}
public bool IsRuntimeSpecialName {
get { return attributes.GetAttributes ((uint) TypeAttributes.RTSpecialName); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.RTSpecialName, value); }
}
public bool HasSecurity {
get { return attributes.GetAttributes ((uint) TypeAttributes.HasSecurity); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.HasSecurity, value); }
}
#endregion
public bool IsForwarder {
get { return attributes.GetAttributes ((uint) TypeAttributes.Forwarder); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Forwarder, value); }
}
public string FullName {
get {
var fullname = string.IsNullOrEmpty (@namespace)
? name
: @namespace + '.' + name;
if (declaring_type != null)
return declaring_type.FullName + "/" + fullname;
return fullname;
}
}
public ExportedType (string @namespace, string name, ModuleDefinition module, IMetadataScope scope)
{
this.@namespace = @namespace;
this.name = name;
this.scope = scope;
this.module = module;
}
public override string ToString ()
{
return FullName;
}
public TypeDefinition Resolve ()
{
return module.Resolve (CreateReference ());
}
internal TypeReference CreateReference ()
{
return new TypeReference (@namespace, name, module, scope) {
DeclaringType = declaring_type != null ? declaring_type.CreateReference () : null,
};
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
[Flags]
internal enum FieldAttributes : ushort {
FieldAccessMask = 0x0007,
CompilerControlled = 0x0000, // Member not referenceable
Private = 0x0001, // Accessible only by the parent type
FamANDAssem = 0x0002, // Accessible by sub-types only in this assembly
Assembly = 0x0003, // Accessible by anyone in the Assembly
Family = 0x0004, // Accessible only by type and sub-types
FamORAssem = 0x0005, // Accessible by sub-types anywhere, plus anyone in the assembly
Public = 0x0006, // Accessible by anyone who has visibility to this scope field contract attributes
Static = 0x0010, // Defined on type, else per instance
InitOnly = 0x0020, // Field may only be initialized, not written after init
Literal = 0x0040, // Value is compile time constant
NotSerialized = 0x0080, // Field does not have to be serialized when type is remoted
SpecialName = 0x0200, // Field is special
// Interop Attributes
PInvokeImpl = 0x2000, // Implementation is forwarded through PInvoke
// Additional flags
RTSpecialName = 0x0400, // CLI provides 'special' behavior, depending upon the name of the field
HasFieldMarshal = 0x1000, // Field has marshalling information
HasDefault = 0x8000, // Field has default
HasFieldRVA = 0x0100 // Field has RVA
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal sealed class FieldDefinition : FieldReference, IMemberDefinition, IConstantProvider, IMarshalInfoProvider {
ushort attributes;
Collection<CustomAttribute> custom_attributes;
int offset = Mixin.NotResolvedMarker;
internal int rva = Mixin.NotResolvedMarker;
byte [] initial_value;
object constant = Mixin.NotResolved;
MarshalInfo marshal_info;
void ResolveLayout ()
{
if (offset != Mixin.NotResolvedMarker)
return;
if (!HasImage) {
offset = Mixin.NoDataMarker;
return;
}
offset = Module.Read (this, (field, reader) => reader.ReadFieldLayout (field));
}
public bool HasLayoutInfo {
get {
if (offset >= 0)
return true;
ResolveLayout ();
return offset >= 0;
}
}
public int Offset {
get {
if (offset >= 0)
return offset;
ResolveLayout ();
return offset >= 0 ? offset : -1;
}
set { offset = value; }
}
internal new FieldDefinitionProjection WindowsRuntimeProjection {
get { return (FieldDefinitionProjection) projection; }
set { projection = value; }
}
void ResolveRVA ()
{
if (rva != Mixin.NotResolvedMarker)
return;
if (!HasImage)
return;
rva = Module.Read (this, (field, reader) => reader.ReadFieldRVA (field));
}
public int RVA {
get {
if (rva > 0)
return rva;
ResolveRVA ();
return rva > 0 ? rva : 0;
}
}
public byte [] InitialValue {
get {
if (initial_value != null)
return initial_value;
ResolveRVA ();
if (initial_value == null)
initial_value = Empty<byte>.Array;
return initial_value;
}
set {
initial_value = value;
rva = 0;
}
}
public FieldAttributes Attributes {
get { return (FieldAttributes) attributes; }
set {
if (IsWindowsRuntimeProjection && (ushort) value != attributes)
throw new InvalidOperationException ();
attributes = (ushort) value;
}
}
public bool HasConstant {
get {
this.ResolveConstant (ref constant, Module);
return constant != Mixin.NoValue;
}
set { if (!value) constant = Mixin.NoValue; }
}
public object Constant {
get { return HasConstant ? constant : null; }
set { constant = value; }
}
public bool HasCustomAttributes {
get {
if (custom_attributes != null)
return custom_attributes.Count > 0;
return this.GetHasCustomAttributes (Module);
}
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); }
}
public bool HasMarshalInfo {
get {
if (marshal_info != null)
return true;
return this.GetHasMarshalInfo (Module);
}
}
public MarshalInfo MarshalInfo {
get { return marshal_info ?? (this.GetMarshalInfo (ref marshal_info, Module)); }
set { marshal_info = value; }
}
#region FieldAttributes
public bool IsCompilerControlled {
get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.CompilerControlled); }
set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.CompilerControlled, value); }
}
public bool IsPrivate {
get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Private); }
set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Private, value); }
}
public bool IsFamilyAndAssembly {
get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamANDAssem); }
set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamANDAssem, value); }
}
public bool IsAssembly {
get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Assembly); }
set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Assembly, value); }
}
public bool IsFamily {
get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Family); }
set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Family, value); }
}
public bool IsFamilyOrAssembly {
get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamORAssem); }
set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamORAssem, value); }
}
public bool IsPublic {
get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Public); }
set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Public, value); }
}
public bool IsStatic {
get { return attributes.GetAttributes ((ushort) FieldAttributes.Static); }
set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.Static, value); }
}
public bool IsInitOnly {
get { return attributes.GetAttributes ((ushort) FieldAttributes.InitOnly); }
set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.InitOnly, value); }
}
public bool IsLiteral {
get { return attributes.GetAttributes ((ushort) FieldAttributes.Literal); }
set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.Literal, value); }
}
public bool IsNotSerialized {
get { return attributes.GetAttributes ((ushort) FieldAttributes.NotSerialized); }
set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.NotSerialized, value); }
}
public bool IsSpecialName {
get { return attributes.GetAttributes ((ushort) FieldAttributes.SpecialName); }
set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.SpecialName, value); }
}
public bool IsPInvokeImpl {
get { return attributes.GetAttributes ((ushort) FieldAttributes.PInvokeImpl); }
set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.PInvokeImpl, value); }
}
public bool IsRuntimeSpecialName {
get { return attributes.GetAttributes ((ushort) FieldAttributes.RTSpecialName); }
set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.RTSpecialName, value); }
}
public bool HasDefault {
get { return attributes.GetAttributes ((ushort) FieldAttributes.HasDefault); }
set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.HasDefault, value); }
}
#endregion
public override bool IsDefinition {
get { return true; }
}
public new TypeDefinition DeclaringType {
get { return (TypeDefinition) base.DeclaringType; }
set { base.DeclaringType = value; }
}
public FieldDefinition (string name, FieldAttributes attributes, TypeReference fieldType)
: base (name, fieldType)
{
this.attributes = (ushort) attributes;
}
public override FieldDefinition Resolve ()
{
return this;
}
}
static partial class Mixin {
public const int NotResolvedMarker = -2;
public const int NoDataMarker = -1;
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
internal class FieldReference : MemberReference {
TypeReference field_type;
public TypeReference FieldType {
get { return field_type; }
set { field_type = value; }
}
public override string FullName {
get { return field_type.FullName + " " + MemberFullName (); }
}
public override bool ContainsGenericParameter {
get { return field_type.ContainsGenericParameter || base.ContainsGenericParameter; }
}
internal FieldReference ()
{
this.token = new MetadataToken (TokenType.MemberRef);
}
public FieldReference (string name, TypeReference fieldType)
: base (name)
{
Mixin.CheckType (fieldType, Mixin.Argument.fieldType);
this.field_type = fieldType;
this.token = new MetadataToken (TokenType.MemberRef);
}
public FieldReference (string name, TypeReference fieldType, TypeReference declaringType)
: this (name, fieldType)
{
Mixin.CheckType (declaringType, Mixin.Argument.declaringType);
this.DeclaringType = declaringType;
}
protected override IMemberDefinition ResolveDefinition ()
{
return this.Resolve ();
}
public new virtual FieldDefinition Resolve ()
{
var module = this.Module;
if (module == null)
throw new NotSupportedException ();
return module.Resolve (this);
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil {
enum FileAttributes : uint {
ContainsMetaData = 0x0000, // This is not a resource file
ContainsNoMetaData = 0x0001, // This is a resource file or other non-metadata-containing file
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Text;
using Mono.Collections.Generic;
using MD = Mono.Cecil.Metadata;
namespace Mono.Cecil {
internal sealed class FunctionPointerType : TypeSpecification, IMethodSignature {
readonly MethodReference function;
public bool HasThis {
get { return function.HasThis; }
set { function.HasThis = value; }
}
public bool ExplicitThis {
get { return function.ExplicitThis; }
set { function.ExplicitThis = value; }
}
public MethodCallingConvention CallingConvention {
get { return function.CallingConvention; }
set { function.CallingConvention = value; }
}
public bool HasParameters {
get { return function.HasParameters; }
}
public Collection<ParameterDefinition> Parameters {
get { return function.Parameters; }
}
public TypeReference ReturnType {
get { return function.MethodReturnType.ReturnType; }
set { function.MethodReturnType.ReturnType = value; }
}
public MethodReturnType MethodReturnType {
get { return function.MethodReturnType; }
}
public override string Name {
get { return function.Name; }
set { throw new InvalidOperationException (); }
}
public override string Namespace {
get { return string.Empty; }
set { throw new InvalidOperationException (); }
}
public override ModuleDefinition Module {
get { return ReturnType.Module; }
}
public override IMetadataScope Scope {
get { return function.ReturnType.Scope; }
set { throw new InvalidOperationException (); }
}
public override bool IsFunctionPointer {
get { return true; }
}
public override bool ContainsGenericParameter {
get { return function.ContainsGenericParameter; }
}
public override string FullName {
get {
var signature = new StringBuilder ();
signature.Append (function.Name);
signature.Append (" ");
signature.Append (function.ReturnType.FullName);
signature.Append (" *");
this.MethodSignatureFullName (signature);
return signature.ToString ();
}
}
public FunctionPointerType ()
: base (null)
{
this.function = new MethodReference ();
this.function.Name = "method";
this.etype = MD.ElementType.FnPtr;
}
public override TypeDefinition Resolve ()
{
return null;
}
public override TypeReference GetElementType ()
{
return this;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Text;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal sealed class GenericInstanceMethod : MethodSpecification, IGenericInstance, IGenericContext {
Collection<TypeReference> arguments;
public bool HasGenericArguments {
get { return !arguments.IsNullOrEmpty (); }
}
public Collection<TypeReference> GenericArguments {
get { return arguments ?? (arguments = new Collection<TypeReference> ()); }
}
public override bool IsGenericInstance {
get { return true; }
}
IGenericParameterProvider IGenericContext.Method {
get { return ElementMethod; }
}
IGenericParameterProvider IGenericContext.Type {
get { return ElementMethod.DeclaringType; }
}
public override bool ContainsGenericParameter {
get { return this.ContainsGenericParameter () || base.ContainsGenericParameter; }
}
public override string FullName {
get {
var signature = new StringBuilder ();
var method = this.ElementMethod;
signature.Append (method.ReturnType.FullName)
.Append (" ")
.Append (method.DeclaringType.FullName)
.Append ("::")
.Append (method.Name);
this.GenericInstanceFullName (signature);
this.MethodSignatureFullName (signature);
return signature.ToString ();
}
}
public GenericInstanceMethod (MethodReference method)
: base (method)
{
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Text;
using Mono.Collections.Generic;
using MD = Mono.Cecil.Metadata;
namespace Mono.Cecil {
internal sealed class GenericInstanceType : TypeSpecification, IGenericInstance, IGenericContext {
Collection<TypeReference> arguments;
public bool HasGenericArguments {
get { return !arguments.IsNullOrEmpty (); }
}
public Collection<TypeReference> GenericArguments {
get { return arguments ?? (arguments = new Collection<TypeReference> ()); }
}
public override TypeReference DeclaringType {
get { return ElementType.DeclaringType; }
set { throw new NotSupportedException (); }
}
public override string FullName {
get {
var name = new StringBuilder ();
name.Append (base.FullName);
this.GenericInstanceFullName (name);
return name.ToString ();
}
}
public override bool IsGenericInstance {
get { return true; }
}
public override bool ContainsGenericParameter {
get { return this.ContainsGenericParameter () || base.ContainsGenericParameter; }
}
IGenericParameterProvider IGenericContext.Type {
get { return ElementType; }
}
public GenericInstanceType (TypeReference type)
: base (type)
{
base.IsValueType = type.IsValueType;
this.etype = MD.ElementType.GenericInst;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Collections.Generic;
using Mono.Cecil.Metadata;
namespace Mono.Cecil {
internal sealed class GenericParameter : TypeReference, ICustomAttributeProvider {
internal int position;
internal GenericParameterType type;
internal IGenericParameterProvider owner;
ushort attributes;
Collection<TypeReference> constraints;
Collection<CustomAttribute> custom_attributes;
public GenericParameterAttributes Attributes {
get { return (GenericParameterAttributes) attributes; }
set { attributes = (ushort) value; }
}
public int Position {
get { return position; }
}
public GenericParameterType Type {
get { return type; }
}
public IGenericParameterProvider Owner {
get { return owner; }
}
public bool HasConstraints {
get {
if (constraints != null)
return constraints.Count > 0;
return HasImage && Module.Read (this, (generic_parameter, reader) => reader.HasGenericConstraints (generic_parameter));
}
}
public Collection<TypeReference> Constraints {
get {
if (constraints != null)
return constraints;
if (HasImage)
return Module.Read (ref constraints, this, (generic_parameter, reader) => reader.ReadGenericConstraints (generic_parameter));
return constraints = new Collection<TypeReference> ();
}
}
public bool HasCustomAttributes {
get {
if (custom_attributes != null)
return custom_attributes.Count > 0;
return this.GetHasCustomAttributes (Module);
}
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); }
}
public override IMetadataScope Scope {
get {
if (owner == null)
return null;
return owner.GenericParameterType == GenericParameterType.Method
? ((MethodReference) owner).DeclaringType.Scope
: ((TypeReference) owner).Scope;
}
set { throw new InvalidOperationException (); }
}
public override TypeReference DeclaringType {
get { return owner as TypeReference; }
set { throw new InvalidOperationException (); }
}
public MethodReference DeclaringMethod {
get { return owner as MethodReference; }
}
public override ModuleDefinition Module {
get { return module ?? owner.Module; }
}
public override string Name {
get {
if (!string.IsNullOrEmpty (base.Name))
return base.Name;
return base.Name = (type == GenericParameterType.Method ? "!!" : "!") + position;
}
}
public override string Namespace {
get { return string.Empty; }
set { throw new InvalidOperationException (); }
}
public override string FullName {
get { return Name; }
}
public override bool IsGenericParameter {
get { return true; }
}
public override bool ContainsGenericParameter {
get { return true; }
}
public override MetadataType MetadataType {
get { return (MetadataType) etype; }
}
#region GenericParameterAttributes
public bool IsNonVariant {
get { return attributes.GetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.NonVariant); }
set { attributes = attributes.SetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.NonVariant, value); }
}
public bool IsCovariant {
get { return attributes.GetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Covariant); }
set { attributes = attributes.SetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Covariant, value); }
}
public bool IsContravariant {
get { return attributes.GetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Contravariant); }
set { attributes = attributes.SetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Contravariant, value); }
}
public bool HasReferenceTypeConstraint {
get { return attributes.GetAttributes ((ushort) GenericParameterAttributes.ReferenceTypeConstraint); }
set { attributes = attributes.SetAttributes ((ushort) GenericParameterAttributes.ReferenceTypeConstraint, value); }
}
public bool HasNotNullableValueTypeConstraint {
get { return attributes.GetAttributes ((ushort) GenericParameterAttributes.NotNullableValueTypeConstraint); }
set { attributes = attributes.SetAttributes ((ushort) GenericParameterAttributes.NotNullableValueTypeConstraint, value); }
}
public bool HasDefaultConstructorConstraint {
get { return attributes.GetAttributes ((ushort) GenericParameterAttributes.DefaultConstructorConstraint); }
set { attributes = attributes.SetAttributes ((ushort) GenericParameterAttributes.DefaultConstructorConstraint, value); }
}
#endregion
public GenericParameter (IGenericParameterProvider owner)
: this (string.Empty, owner)
{
}
public GenericParameter (string name, IGenericParameterProvider owner)
: base (string.Empty, name)
{
if (owner == null)
throw new ArgumentNullException ();
this.position = -1;
this.owner = owner;
this.type = owner.GenericParameterType;
this.etype = ConvertGenericParameterType (this.type);
this.token = new MetadataToken (TokenType.GenericParam);
}
internal GenericParameter (int position, GenericParameterType type, ModuleDefinition module)
: base (string.Empty, string.Empty)
{
Mixin.CheckModule (module);
this.position = position;
this.type = type;
this.etype = ConvertGenericParameterType (type);
this.module = module;
this.token = new MetadataToken (TokenType.GenericParam);
}
static ElementType ConvertGenericParameterType (GenericParameterType type)
{
switch (type) {
case GenericParameterType.Type:
return ElementType.Var;
case GenericParameterType.Method:
return ElementType.MVar;
}
throw new ArgumentOutOfRangeException ();
}
public override TypeDefinition Resolve ()
{
return null;
}
}
sealed class GenericParameterCollection : Collection<GenericParameter> {
readonly IGenericParameterProvider owner;
internal GenericParameterCollection (IGenericParameterProvider owner)
{
this.owner = owner;
}
internal GenericParameterCollection (IGenericParameterProvider owner, int capacity)
: base (capacity)
{
this.owner = owner;
}
protected override void OnAdd (GenericParameter item, int index)
{
UpdateGenericParameter (item, index);
}
protected override void OnInsert (GenericParameter item, int index)
{
UpdateGenericParameter (item, index);
for (int i = index; i < size; i++)
items[i].position = i + 1;
}
protected override void OnSet (GenericParameter item, int index)
{
UpdateGenericParameter (item, index);
}
void UpdateGenericParameter (GenericParameter item, int index)
{
item.owner = owner;
item.position = index;
item.type = owner.GenericParameterType;
}
protected override void OnRemove (GenericParameter item, int index)
{
item.owner = null;
item.position = -1;
item.type = GenericParameterType.Type;
for (int i = index + 1; i < size; i++)
items[i].position = i - 1;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
[Flags]
internal enum GenericParameterAttributes : ushort {
VarianceMask = 0x0003,
NonVariant = 0x0000,
Covariant = 0x0001,
Contravariant = 0x0002,
SpecialConstraintMask = 0x001c,
ReferenceTypeConstraint = 0x0004,
NotNullableValueTypeConstraint = 0x0008,
DefaultConstructorConstraint = 0x0010
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil {
internal interface IConstantProvider : IMetadataTokenProvider {
bool HasConstant { get; set; }
object Constant { get; set; }
}
static partial class Mixin {
internal static object NoValue = new object ();
internal static object NotResolved = new object ();
public static void ResolveConstant (
this IConstantProvider self,
ref object constant,
ModuleDefinition module)
{
if (module == null) {
constant = Mixin.NoValue;
return;
}
lock (module.SyncRoot) {
if (constant != Mixin.NotResolved)
return;
if (module.HasImage ())
constant = module.Read (self, (provider, reader) => reader.ReadConstant (provider));
else
constant = Mixin.NoValue;
}
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal interface ICustomAttributeProvider : IMetadataTokenProvider {
Collection<CustomAttribute> CustomAttributes { get; }
bool HasCustomAttributes { get; }
}
static partial class Mixin {
public static bool GetHasCustomAttributes (
this ICustomAttributeProvider self,
ModuleDefinition module)
{
return module.HasImage () && module.Read (self, (provider, reader) => reader.HasCustomAttributes (provider));
}
public static Collection<CustomAttribute> GetCustomAttributes (
this ICustomAttributeProvider self,
ref Collection<CustomAttribute> variable,
ModuleDefinition module)
{
return module.HasImage ()
? module.Read (ref variable, self, (provider, reader) => reader.ReadCustomAttributes (provider))
: variable = new Collection<CustomAttribute>();
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System.Text;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal interface IGenericInstance : IMetadataTokenProvider {
bool HasGenericArguments { get; }
Collection<TypeReference> GenericArguments { get; }
}
static partial class Mixin {
public static bool ContainsGenericParameter (this IGenericInstance self)
{
var arguments = self.GenericArguments;
for (int i = 0; i < arguments.Count; i++)
if (arguments [i].ContainsGenericParameter)
return true;
return false;
}
public static void GenericInstanceFullName (this IGenericInstance self, StringBuilder builder)
{
builder.Append ("<");
var arguments = self.GenericArguments;
for (int i = 0; i < arguments.Count; i++) {
if (i > 0)
builder.Append (",");
builder.Append (arguments [i].FullName);
}
builder.Append (">");
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal interface IGenericParameterProvider : IMetadataTokenProvider {
bool HasGenericParameters { get; }
bool IsDefinition { get; }
ModuleDefinition Module { get; }
Collection<GenericParameter> GenericParameters { get; }
GenericParameterType GenericParameterType { get; }
}
internal enum GenericParameterType {
Type,
Method
}
interface IGenericContext {
bool IsDefinition { get; }
IGenericParameterProvider Type { get; }
IGenericParameterProvider Method { get; }
}
static partial class Mixin {
public static bool GetHasGenericParameters (
this IGenericParameterProvider self,
ModuleDefinition module)
{
return module.HasImage () && module.Read (self, (provider, reader) => reader.HasGenericParameters (provider));
}
public static Collection<GenericParameter> GetGenericParameters (
this IGenericParameterProvider self,
ref Collection<GenericParameter> collection,
ModuleDefinition module)
{
return module.HasImage ()
? module.Read (ref collection, self, (provider, reader) => reader.ReadGenericParameters (provider))
: collection = new GenericParameterCollection (self);
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil {
internal interface IMarshalInfoProvider : IMetadataTokenProvider {
bool HasMarshalInfo { get; }
MarshalInfo MarshalInfo { get; set; }
}
static partial class Mixin {
public static bool GetHasMarshalInfo (
this IMarshalInfoProvider self,
ModuleDefinition module)
{
return module.HasImage () && module.Read (self, (provider, reader) => reader.HasMarshalInfo (provider));
}
public static MarshalInfo GetMarshalInfo (
this IMarshalInfoProvider self,
ref MarshalInfo variable,
ModuleDefinition module)
{
return module.HasImage ()
? module.Read (ref variable, self, (provider, reader) => reader.ReadMarshalInfo (provider))
: null;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil {
internal interface IMemberDefinition : ICustomAttributeProvider {
string Name { get; set; }
string FullName { get; }
bool IsSpecialName { get; set; }
bool IsRuntimeSpecialName { get; set; }
TypeDefinition DeclaringType { get; set; }
}
static partial class Mixin {
public static bool GetAttributes (this uint self, uint attributes)
{
return (self & attributes) != 0;
}
public static uint SetAttributes (this uint self, uint attributes, bool value)
{
if (value)
return self | attributes;
return self & ~attributes;
}
public static bool GetMaskedAttributes (this uint self, uint mask, uint attributes)
{
return (self & mask) == attributes;
}
public static uint SetMaskedAttributes (this uint self, uint mask, uint attributes, bool value)
{
if (value) {
self &= ~mask;
return self | attributes;
}
return self & ~(mask & attributes);
}
public static bool GetAttributes (this ushort self, ushort attributes)
{
return (self & attributes) != 0;
}
public static ushort SetAttributes (this ushort self, ushort attributes, bool value)
{
if (value)
return (ushort) (self | attributes);
return (ushort) (self & ~attributes);
}
public static bool GetMaskedAttributes (this ushort self, ushort mask, uint attributes)
{
return (self & mask) == attributes;
}
public static ushort SetMaskedAttributes (this ushort self, ushort mask, uint attributes, bool value)
{
if (value) {
self = (ushort) (self & ~mask);
return (ushort) (self | attributes);
}
return (ushort) (self & ~(mask & attributes));
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil {
internal enum MetadataScopeType {
AssemblyNameReference,
ModuleReference,
ModuleDefinition,
}
internal interface IMetadataScope : IMetadataTokenProvider {
MetadataScopeType MetadataScopeType { get; }
string Name { get; set; }
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil {
internal interface IMetadataTokenProvider {
MetadataToken MetadataToken { get; set; }
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System.Text;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal interface IMethodSignature : IMetadataTokenProvider {
bool HasThis { get; set; }
bool ExplicitThis { get; set; }
MethodCallingConvention CallingConvention { get; set; }
bool HasParameters { get; }
Collection<ParameterDefinition> Parameters { get; }
TypeReference ReturnType { get; set; }
MethodReturnType MethodReturnType { get; }
}
static partial class Mixin {
public static bool HasImplicitThis (this IMethodSignature self)
{
return self.HasThis && !self.ExplicitThis;
}
public static void MethodSignatureFullName (this IMethodSignature self, StringBuilder builder)
{
builder.Append ("(");
if (self.HasParameters) {
var parameters = self.Parameters;
for (int i = 0; i < parameters.Count; i++) {
var parameter = parameters [i];
if (i > 0)
builder.Append (",");
if (parameter.ParameterType.IsSentinel)
builder.Append ("...,");
builder.Append (parameter.ParameterType.FullName);
}
}
builder.Append (")");
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Collections.Generic;
using Mono.Collections.Generic;
using SR = System.Reflection;
using Mono.Cecil.Metadata;
namespace Mono.Cecil {
#if !READ_ONLY
internal interface IMetadataImporterProvider {
IMetadataImporter GetMetadataImporter (ModuleDefinition module);
}
internal interface IMetadataImporter {
AssemblyNameReference ImportReference (AssemblyNameReference reference);
TypeReference ImportReference (TypeReference type, IGenericParameterProvider context);
FieldReference ImportReference (FieldReference field, IGenericParameterProvider context);
MethodReference ImportReference (MethodReference method, IGenericParameterProvider context);
}
internal interface IReflectionImporterProvider {
IReflectionImporter GetReflectionImporter (ModuleDefinition module);
}
internal interface IReflectionImporter {
AssemblyNameReference ImportReference (SR.AssemblyName reference);
TypeReference ImportReference (Type type, IGenericParameterProvider context);
FieldReference ImportReference (SR.FieldInfo field, IGenericParameterProvider context);
MethodReference ImportReference (SR.MethodBase method, IGenericParameterProvider context);
}
struct ImportGenericContext {
Collection<IGenericParameterProvider> stack;
public bool IsEmpty { get { return stack == null; } }
public ImportGenericContext (IGenericParameterProvider provider)
{
if (provider == null)
throw new ArgumentNullException ("provider");
stack = null;
Push (provider);
}
public void Push (IGenericParameterProvider provider)
{
if (stack == null)
stack = new Collection<IGenericParameterProvider> (1) { provider };
else
stack.Add (provider);
}
public void Pop ()
{
stack.RemoveAt (stack.Count - 1);
}
public TypeReference MethodParameter (string method, int position)
{
for (int i = stack.Count - 1; i >= 0; i--) {
var candidate = stack [i] as MethodReference;
if (candidate == null)
continue;
if (method != NormalizeMethodName (candidate))
continue;
return candidate.GenericParameters [position];
}
throw new InvalidOperationException ();
}
public string NormalizeMethodName (MethodReference method)
{
return method.DeclaringType.GetElementType ().FullName + "." + method.Name;
}
public TypeReference TypeParameter (string type, int position)
{
for (int i = stack.Count - 1; i >= 0; i--) {
var candidate = GenericTypeFor (stack [i]);
if (candidate.FullName != type)
continue;
return candidate.GenericParameters [position];
}
throw new InvalidOperationException ();
}
static TypeReference GenericTypeFor (IGenericParameterProvider context)
{
var type = context as TypeReference;
if (type != null)
return type.GetElementType ();
var method = context as MethodReference;
if (method != null)
return method.DeclaringType.GetElementType ();
throw new InvalidOperationException ();
}
public static ImportGenericContext For (IGenericParameterProvider context)
{
return context != null ? new ImportGenericContext (context) : default (ImportGenericContext);
}
}
internal class DefaultReflectionImporter : IReflectionImporter {
readonly protected ModuleDefinition module;
public DefaultReflectionImporter (ModuleDefinition module)
{
Mixin.CheckModule (module);
this.module = module;
}
enum ImportGenericKind {
Definition,
Open,
}
static readonly Dictionary<Type, ElementType> type_etype_mapping = new Dictionary<Type, ElementType> (18) {
{ typeof (void), ElementType.Void },
{ typeof (bool), ElementType.Boolean },
{ typeof (char), ElementType.Char },
{ typeof (sbyte), ElementType.I1 },
{ typeof (byte), ElementType.U1 },
{ typeof (short), ElementType.I2 },
{ typeof (ushort), ElementType.U2 },
{ typeof (int), ElementType.I4 },
{ typeof (uint), ElementType.U4 },
{ typeof (long), ElementType.I8 },
{ typeof (ulong), ElementType.U8 },
{ typeof (float), ElementType.R4 },
{ typeof (double), ElementType.R8 },
{ typeof (string), ElementType.String },
#if !NET_CORE
{ typeof (TypedReference), ElementType.TypedByRef },
#endif
{ typeof (IntPtr), ElementType.I },
{ typeof (UIntPtr), ElementType.U },
{ typeof (object), ElementType.Object },
};
TypeReference ImportType (Type type, ImportGenericContext context)
{
return ImportType (type, context, ImportGenericKind.Open);
}
TypeReference ImportType (Type type, ImportGenericContext context, ImportGenericKind import_kind)
{
if (IsTypeSpecification (type) || ImportOpenGenericType (type, import_kind))
return ImportTypeSpecification (type, context);
var reference = new TypeReference (
string.Empty,
type.Name,
module,
ImportScope (type),
type.IsValueType ());
reference.etype = ImportElementType (type);
if (IsNestedType (type))
reference.DeclaringType = ImportType (type.DeclaringType, context, import_kind);
else
reference.Namespace = type.Namespace ?? string.Empty;
if (type.IsGenericType ())
ImportGenericParameters (reference, type.GetGenericArguments ());
return reference;
}
protected virtual IMetadataScope ImportScope (Type type)
{
return ImportScope (type.Assembly ());
}
static bool ImportOpenGenericType (Type type, ImportGenericKind import_kind)
{
return type.IsGenericType () && type.IsGenericTypeDefinition () && import_kind == ImportGenericKind.Open;
}
static bool ImportOpenGenericMethod (SR.MethodBase method, ImportGenericKind import_kind)
{
return method.IsGenericMethod && method.IsGenericMethodDefinition && import_kind == ImportGenericKind.Open;
}
static bool IsNestedType (Type type)
{
return type.IsNested;
}
TypeReference ImportTypeSpecification (Type type, ImportGenericContext context)
{
if (type.IsByRef)
return new ByReferenceType (ImportType (type.GetElementType (), context));
if (type.IsPointer)
return new PointerType (ImportType (type.GetElementType (), context));
if (type.IsArray)
return new ArrayType (ImportType (type.GetElementType (), context), type.GetArrayRank ());
if (type.IsGenericType ())
return ImportGenericInstance (type, context);
if (type.IsGenericParameter)
return ImportGenericParameter (type, context);
throw new NotSupportedException (type.FullName);
}
static TypeReference ImportGenericParameter (Type type, ImportGenericContext context)
{
if (context.IsEmpty)
throw new InvalidOperationException ();
if (type.DeclaringMethod () != null)
return context.MethodParameter (NormalizeMethodName (type.DeclaringMethod ()), type.GenericParameterPosition);
if (type.DeclaringType != null)
return context.TypeParameter (NormalizeTypeFullName (type.DeclaringType), type.GenericParameterPosition);
throw new InvalidOperationException();
}
static string NormalizeMethodName (SR.MethodBase method)
{
return NormalizeTypeFullName (method.DeclaringType) + "." + method.Name;
}
static string NormalizeTypeFullName (Type type)
{
if (IsNestedType (type))
return NormalizeTypeFullName (type.DeclaringType) + "/" + type.Name;
return type.FullName;
}
TypeReference ImportGenericInstance (Type type, ImportGenericContext context)
{
var element_type = ImportType (type.GetGenericTypeDefinition (), context, ImportGenericKind.Definition);
var instance = new GenericInstanceType (element_type);
var arguments = type.GetGenericArguments ();
var instance_arguments = instance.GenericArguments;
context.Push (element_type);
try {
for (int i = 0; i < arguments.Length; i++)
instance_arguments.Add (ImportType (arguments [i], context));
return instance;
} finally {
context.Pop ();
}
}
static bool IsTypeSpecification (Type type)
{
return type.HasElementType
|| IsGenericInstance (type)
|| type.IsGenericParameter;
}
static bool IsGenericInstance (Type type)
{
return type.IsGenericType () && !type.IsGenericTypeDefinition ();
}
static ElementType ImportElementType (Type type)
{
ElementType etype;
if (!type_etype_mapping.TryGetValue (type, out etype))
return ElementType.None;
return etype;
}
protected AssemblyNameReference ImportScope (SR.Assembly assembly)
{
return ImportReference (assembly.GetName ());
}
public virtual AssemblyNameReference ImportReference (SR.AssemblyName name)
{
Mixin.CheckName (name);
AssemblyNameReference reference;
if (TryGetAssemblyNameReference (name, out reference))
return reference;
reference = new AssemblyNameReference (name.Name, name.Version)
{
PublicKeyToken = name.GetPublicKeyToken (),
#if !NET_CORE
Culture = name.CultureInfo.Name,
HashAlgorithm = (AssemblyHashAlgorithm) name.HashAlgorithm,
#endif
};
module.AssemblyReferences.Add (reference);
return reference;
}
bool TryGetAssemblyNameReference (SR.AssemblyName name, out AssemblyNameReference assembly_reference)
{
var references = module.AssemblyReferences;
for (int i = 0; i < references.Count; i++) {
var reference = references [i];
if (name.FullName != reference.FullName) // TODO compare field by field
continue;
assembly_reference = reference;
return true;
}
assembly_reference = null;
return false;
}
FieldReference ImportField (SR.FieldInfo field, ImportGenericContext context)
{
var declaring_type = ImportType (field.DeclaringType, context);
if (IsGenericInstance (field.DeclaringType))
field = ResolveFieldDefinition (field);
context.Push (declaring_type);
try {
return new FieldReference {
Name = field.Name,
DeclaringType = declaring_type,
FieldType = ImportType (field.FieldType, context),
};
} finally {
context.Pop ();
}
}
static SR.FieldInfo ResolveFieldDefinition (SR.FieldInfo field)
{
#if NET_CORE
throw new NotImplementedException ();
#else
return field.Module.ResolveField (field.MetadataToken);
#endif
}
static SR.MethodBase ResolveMethodDefinition (SR.MethodBase method)
{
#if NET_CORE
throw new NotImplementedException ();
#else
return method.Module.ResolveMethod (method.MetadataToken);
#endif
}
MethodReference ImportMethod (SR.MethodBase method, ImportGenericContext context, ImportGenericKind import_kind)
{
if (IsMethodSpecification (method) || ImportOpenGenericMethod (method, import_kind))
return ImportMethodSpecification (method, context);
var declaring_type = ImportType (method.DeclaringType, context);
if (IsGenericInstance (method.DeclaringType))
method = ResolveMethodDefinition (method);
var reference = new MethodReference {
Name = method.Name,
HasThis = HasCallingConvention (method, SR.CallingConventions.HasThis),
ExplicitThis = HasCallingConvention (method, SR.CallingConventions.ExplicitThis),
DeclaringType = ImportType (method.DeclaringType, context, ImportGenericKind.Definition),
};
if (HasCallingConvention (method, SR.CallingConventions.VarArgs))
reference.CallingConvention &= MethodCallingConvention.VarArg;
if (method.IsGenericMethod)
ImportGenericParameters (reference, method.GetGenericArguments ());
context.Push (reference);
try {
var method_info = method as SR.MethodInfo;
reference.ReturnType = method_info != null
? ImportType (method_info.ReturnType, context)
: ImportType (typeof (void), default (ImportGenericContext));
var parameters = method.GetParameters ();
var reference_parameters = reference.Parameters;
for (int i = 0; i < parameters.Length; i++)
reference_parameters.Add (
new ParameterDefinition (ImportType (parameters [i].ParameterType, context)));
reference.DeclaringType = declaring_type;
return reference;
} finally {
context.Pop ();
}
}
static void ImportGenericParameters (IGenericParameterProvider provider, Type [] arguments)
{
var provider_parameters = provider.GenericParameters;
for (int i = 0; i < arguments.Length; i++)
provider_parameters.Add (new GenericParameter (arguments [i].Name, provider));
}
static bool IsMethodSpecification (SR.MethodBase method)
{
return method.IsGenericMethod && !method.IsGenericMethodDefinition;
}
MethodReference ImportMethodSpecification (SR.MethodBase method, ImportGenericContext context)
{
var method_info = method as SR.MethodInfo;
if (method_info == null)
throw new InvalidOperationException ();
var element_method = ImportMethod (method_info.GetGenericMethodDefinition (), context, ImportGenericKind.Definition);
var instance = new GenericInstanceMethod (element_method);
var arguments = method.GetGenericArguments ();
var instance_arguments = instance.GenericArguments;
context.Push (element_method);
try {
for (int i = 0; i < arguments.Length; i++)
instance_arguments.Add (ImportType (arguments [i], context));
return instance;
} finally {
context.Pop ();
}
}
static bool HasCallingConvention (SR.MethodBase method, SR.CallingConventions conventions)
{
return (method.CallingConvention & conventions) != 0;
}
public virtual TypeReference ImportReference (Type type, IGenericParameterProvider context)
{
Mixin.CheckType (type);
return ImportType (
type,
ImportGenericContext.For (context),
context != null ? ImportGenericKind.Open : ImportGenericKind.Definition);
}
public virtual FieldReference ImportReference (SR.FieldInfo field, IGenericParameterProvider context)
{
Mixin.CheckField (field);
return ImportField (field, ImportGenericContext.For (context));
}
public virtual MethodReference ImportReference (SR.MethodBase method, IGenericParameterProvider context)
{
Mixin.CheckMethod (method);
return ImportMethod (method,
ImportGenericContext.For (context),
context != null ? ImportGenericKind.Open : ImportGenericKind.Definition);
}
}
internal class DefaultMetadataImporter : IMetadataImporter {
readonly protected ModuleDefinition module;
public DefaultMetadataImporter (ModuleDefinition module)
{
Mixin.CheckModule (module);
this.module = module;
}
TypeReference ImportType (TypeReference type, ImportGenericContext context)
{
if (type.IsTypeSpecification ())
return ImportTypeSpecification (type, context);
var reference = new TypeReference (
type.Namespace,
type.Name,
module,
ImportScope (type),
type.IsValueType);
MetadataSystem.TryProcessPrimitiveTypeReference (reference);
if (type.IsNested)
reference.DeclaringType = ImportType (type.DeclaringType, context);
if (type.HasGenericParameters)
ImportGenericParameters (reference, type);
return reference;
}
protected virtual IMetadataScope ImportScope (TypeReference type)
{
return ImportScope (type.Scope);
}
protected IMetadataScope ImportScope (IMetadataScope scope)
{
switch (scope.MetadataScopeType) {
case MetadataScopeType.AssemblyNameReference:
return ImportReference ((AssemblyNameReference) scope);
case MetadataScopeType.ModuleDefinition:
if (scope == module) return scope;
return ImportReference (((ModuleDefinition) scope).Assembly.Name);
case MetadataScopeType.ModuleReference:
throw new NotImplementedException ();
}
throw new NotSupportedException ();
}
public virtual AssemblyNameReference ImportReference (AssemblyNameReference name)
{
Mixin.CheckName (name);
AssemblyNameReference reference;
if (module.TryGetAssemblyNameReference (name, out reference))
return reference;
reference = new AssemblyNameReference (name.Name, name.Version) {
Culture = name.Culture,
HashAlgorithm = name.HashAlgorithm,
IsRetargetable = name.IsRetargetable,
IsWindowsRuntime = name.IsWindowsRuntime,
};
var pk_token = !name.PublicKeyToken.IsNullOrEmpty ()
? new byte [name.PublicKeyToken.Length]
: Empty<byte>.Array;
if (pk_token.Length > 0)
Buffer.BlockCopy (name.PublicKeyToken, 0, pk_token, 0, pk_token.Length);
reference.PublicKeyToken = pk_token;
module.AssemblyReferences.Add (reference);
return reference;
}
static void ImportGenericParameters (IGenericParameterProvider imported, IGenericParameterProvider original)
{
var parameters = original.GenericParameters;
var imported_parameters = imported.GenericParameters;
for (int i = 0; i < parameters.Count; i++)
imported_parameters.Add (new GenericParameter (parameters [i].Name, imported));
}
TypeReference ImportTypeSpecification (TypeReference type, ImportGenericContext context)
{
switch (type.etype) {
case ElementType.SzArray:
var vector = (ArrayType) type;
return new ArrayType (ImportType (vector.ElementType, context));
case ElementType.Ptr:
var pointer = (PointerType) type;
return new PointerType (ImportType (pointer.ElementType, context));
case ElementType.ByRef:
var byref = (ByReferenceType) type;
return new ByReferenceType (ImportType (byref.ElementType, context));
case ElementType.Pinned:
var pinned = (PinnedType) type;
return new PinnedType (ImportType (pinned.ElementType, context));
case ElementType.Sentinel:
var sentinel = (SentinelType) type;
return new SentinelType (ImportType (sentinel.ElementType, context));
case ElementType.FnPtr:
var fnptr = (FunctionPointerType) type;
var imported_fnptr = new FunctionPointerType () {
HasThis = fnptr.HasThis,
ExplicitThis = fnptr.ExplicitThis,
CallingConvention = fnptr.CallingConvention,
ReturnType = ImportType (fnptr.ReturnType, context),
};
if (!fnptr.HasParameters)
return imported_fnptr;
for (int i = 0; i < fnptr.Parameters.Count; i++)
imported_fnptr.Parameters.Add (new ParameterDefinition (
ImportType (fnptr.Parameters [i].ParameterType, context)));
return imported_fnptr;
case ElementType.CModOpt:
var modopt = (OptionalModifierType) type;
return new OptionalModifierType (
ImportType (modopt.ModifierType, context),
ImportType (modopt.ElementType, context));
case ElementType.CModReqD:
var modreq = (RequiredModifierType) type;
return new RequiredModifierType (
ImportType (modreq.ModifierType, context),
ImportType (modreq.ElementType, context));
case ElementType.Array:
var array = (ArrayType) type;
var imported_array = new ArrayType (ImportType (array.ElementType, context));
if (array.IsVector)
return imported_array;
var dimensions = array.Dimensions;
var imported_dimensions = imported_array.Dimensions;
imported_dimensions.Clear ();
for (int i = 0; i < dimensions.Count; i++) {
var dimension = dimensions [i];
imported_dimensions.Add (new ArrayDimension (dimension.LowerBound, dimension.UpperBound));
}
return imported_array;
case ElementType.GenericInst:
var instance = (GenericInstanceType) type;
var element_type = ImportType (instance.ElementType, context);
var imported_instance = new GenericInstanceType (element_type);
var arguments = instance.GenericArguments;
var imported_arguments = imported_instance.GenericArguments;
for (int i = 0; i < arguments.Count; i++)
imported_arguments.Add (ImportType (arguments [i], context));
return imported_instance;
case ElementType.Var:
var var_parameter = (GenericParameter) type;
if (var_parameter.DeclaringType == null)
throw new InvalidOperationException ();
return context.TypeParameter (var_parameter.DeclaringType.FullName, var_parameter.Position);
case ElementType.MVar:
var mvar_parameter = (GenericParameter) type;
if (mvar_parameter.DeclaringMethod == null)
throw new InvalidOperationException ();
return context.MethodParameter (context.NormalizeMethodName (mvar_parameter.DeclaringMethod), mvar_parameter.Position);
}
throw new NotSupportedException (type.etype.ToString ());
}
FieldReference ImportField (FieldReference field, ImportGenericContext context)
{
var declaring_type = ImportType (field.DeclaringType, context);
context.Push (declaring_type);
try {
return new FieldReference {
Name = field.Name,
DeclaringType = declaring_type,
FieldType = ImportType (field.FieldType, context),
};
} finally {
context.Pop ();
}
}
MethodReference ImportMethod (MethodReference method, ImportGenericContext context)
{
if (method.IsGenericInstance)
return ImportMethodSpecification (method, context);
var declaring_type = ImportType (method.DeclaringType, context);
var reference = new MethodReference {
Name = method.Name,
HasThis = method.HasThis,
ExplicitThis = method.ExplicitThis,
DeclaringType = declaring_type,
CallingConvention = method.CallingConvention,
};
if (method.HasGenericParameters)
ImportGenericParameters (reference, method);
context.Push (reference);
try {
reference.ReturnType = ImportType (method.ReturnType, context);
if (!method.HasParameters)
return reference;
var parameters = method.Parameters;
var reference_parameters = reference.parameters = new ParameterDefinitionCollection (reference, parameters.Count);
for (int i = 0; i < parameters.Count; i++)
reference_parameters.Add (
new ParameterDefinition (ImportType (parameters [i].ParameterType, context)));
return reference;
} finally {
context.Pop();
}
}
MethodSpecification ImportMethodSpecification (MethodReference method, ImportGenericContext context)
{
if (!method.IsGenericInstance)
throw new NotSupportedException ();
var instance = (GenericInstanceMethod) method;
var element_method = ImportMethod (instance.ElementMethod, context);
var imported_instance = new GenericInstanceMethod (element_method);
var arguments = instance.GenericArguments;
var imported_arguments = imported_instance.GenericArguments;
for (int i = 0; i < arguments.Count; i++)
imported_arguments.Add (ImportType (arguments [i], context));
return imported_instance;
}
public virtual TypeReference ImportReference (TypeReference type, IGenericParameterProvider context)
{
Mixin.CheckType (type);
return ImportType (type, ImportGenericContext.For (context));
}
public virtual FieldReference ImportReference (FieldReference field, IGenericParameterProvider context)
{
Mixin.CheckField (field);
return ImportField (field, ImportGenericContext.For (context));
}
public virtual MethodReference ImportReference (MethodReference method, IGenericParameterProvider context)
{
Mixin.CheckMethod (method);
return ImportMethod (method, ImportGenericContext.For (context));
}
}
#endif
static partial class Mixin {
public static void CheckModule (ModuleDefinition module)
{
if (module == null)
throw new ArgumentNullException (Argument.module.ToString ());
}
public static bool TryGetAssemblyNameReference (this ModuleDefinition module, AssemblyNameReference name_reference, out AssemblyNameReference assembly_reference)
{
var references = module.AssemblyReferences;
for (int i = 0; i < references.Count; i++) {
var reference = references [i];
if (!Equals (name_reference, reference))
continue;
assembly_reference = reference;
return true;
}
assembly_reference = null;
return false;
}
static bool Equals (byte [] a, byte [] b)
{
if (ReferenceEquals (a, b))
return true;
if (a == null)
return false;
if (a.Length != b.Length)
return false;
for (int i = 0; i < a.Length; i++)
if (a [i] != b [i])
return false;
return true;
}
static bool Equals<T> (T a, T b) where T : class, IEquatable<T>
{
if (ReferenceEquals (a, b))
return true;
if (a == null)
return false;
return a.Equals (b);
}
static bool Equals (AssemblyNameReference a, AssemblyNameReference b)
{
if (ReferenceEquals (a, b))
return true;
if (a.Name != b.Name)
return false;
if (!Equals (a.Version, b.Version))
return false;
if (a.Culture != b.Culture)
return false;
if (!Equals (a.PublicKeyToken, b.PublicKeyToken))
return false;
return true;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil {
internal sealed class LinkedResource : Resource {
internal byte [] hash;
string file;
public byte [] Hash {
get { return hash; }
}
public string File {
get { return file; }
set { file = value; }
}
public override ResourceType ResourceType {
get { return ResourceType.Linked; }
}
public LinkedResource (string name, ManifestResourceAttributes flags)
: base (name, flags)
{
}
public LinkedResource (string name, ManifestResourceAttributes flags, string file)
: base (name, flags)
{
this.file = file;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
[Flags]
internal enum ManifestResourceAttributes : uint {
VisibilityMask = 0x0007,
Public = 0x0001, // The resource is exported from the Assembly
Private = 0x0002 // The resource is private to the Assembly
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
internal class MarshalInfo {
internal NativeType native;
public NativeType NativeType {
get { return native; }
set { native = value; }
}
public MarshalInfo (NativeType native)
{
this.native = native;
}
}
internal sealed class ArrayMarshalInfo : MarshalInfo {
internal NativeType element_type;
internal int size_parameter_index;
internal int size;
internal int size_parameter_multiplier;
public NativeType ElementType {
get { return element_type; }
set { element_type = value; }
}
public int SizeParameterIndex {
get { return size_parameter_index; }
set { size_parameter_index = value; }
}
public int Size {
get { return size; }
set { size = value; }
}
public int SizeParameterMultiplier {
get { return size_parameter_multiplier; }
set { size_parameter_multiplier = value; }
}
public ArrayMarshalInfo ()
: base (NativeType.Array)
{
element_type = NativeType.None;
size_parameter_index = -1;
size = -1;
size_parameter_multiplier = -1;
}
}
internal sealed class CustomMarshalInfo : MarshalInfo {
internal Guid guid;
internal string unmanaged_type;
internal TypeReference managed_type;
internal string cookie;
public Guid Guid {
get { return guid; }
set { guid = value; }
}
public string UnmanagedType {
get { return unmanaged_type; }
set { unmanaged_type = value; }
}
public TypeReference ManagedType {
get { return managed_type; }
set { managed_type = value; }
}
public string Cookie {
get { return cookie; }
set { cookie = value; }
}
public CustomMarshalInfo ()
: base (NativeType.CustomMarshaler)
{
}
}
internal sealed class SafeArrayMarshalInfo : MarshalInfo {
internal VariantType element_type;
public VariantType ElementType {
get { return element_type; }
set { element_type = value; }
}
public SafeArrayMarshalInfo ()
: base (NativeType.SafeArray)
{
element_type = VariantType.None;
}
}
internal sealed class FixedArrayMarshalInfo : MarshalInfo {
internal NativeType element_type;
internal int size;
public NativeType ElementType {
get { return element_type; }
set { element_type = value; }
}
public int Size {
get { return size; }
set { size = value; }
}
public FixedArrayMarshalInfo ()
: base (NativeType.FixedArray)
{
element_type = NativeType.None;
}
}
internal sealed class FixedSysStringMarshalInfo : MarshalInfo {
internal int size;
public int Size {
get { return size; }
set { size = value; }
}
public FixedSysStringMarshalInfo ()
: base (NativeType.FixedSysString)
{
size = -1;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Collections.Generic;
namespace Mono.Cecil {
sealed class MemberDefinitionCollection<T> : Collection<T> where T : IMemberDefinition {
TypeDefinition container;
internal MemberDefinitionCollection (TypeDefinition container)
{
this.container = container;
}
internal MemberDefinitionCollection (TypeDefinition container, int capacity)
: base (capacity)
{
this.container = container;
}
protected override void OnAdd (T item, int index)
{
Attach (item);
}
protected sealed override void OnSet (T item, int index)
{
Attach (item);
}
protected sealed override void OnInsert (T item, int index)
{
Attach (item);
}
protected sealed override void OnRemove (T item, int index)
{
Detach (item);
}
protected sealed override void OnClear ()
{
foreach (var definition in this)
Detach (definition);
}
void Attach (T element)
{
if (element.DeclaringType == container)
return;
if (element.DeclaringType != null)
throw new ArgumentException ("Member already attached");
element.DeclaringType = this.container;
}
static void Detach (T element)
{
element.DeclaringType = null;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
internal abstract class MemberReference : IMetadataTokenProvider {
string name;
TypeReference declaring_type;
internal MetadataToken token;
internal object projection;
public virtual string Name {
get { return name; }
set {
if (IsWindowsRuntimeProjection && value != name)
throw new InvalidOperationException ();
name = value;
}
}
public abstract string FullName {
get;
}
public virtual TypeReference DeclaringType {
get { return declaring_type; }
set { declaring_type = value; }
}
public MetadataToken MetadataToken {
get { return token; }
set { token = value; }
}
public bool IsWindowsRuntimeProjection {
get { return projection != null; }
}
internal MemberReferenceProjection WindowsRuntimeProjection {
get { return (MemberReferenceProjection) projection; }
set { projection = value; }
}
internal bool HasImage {
get {
var module = Module;
if (module == null)
return false;
return module.HasImage;
}
}
public virtual ModuleDefinition Module {
get { return declaring_type != null ? declaring_type.Module : null; }
}
public virtual bool IsDefinition {
get { return false; }
}
public virtual bool ContainsGenericParameter {
get { return declaring_type != null && declaring_type.ContainsGenericParameter; }
}
internal MemberReference ()
{
}
internal MemberReference (string name)
{
this.name = name ?? string.Empty;
}
internal string MemberFullName ()
{
if (declaring_type == null)
return name;
return declaring_type.FullName + "::" + name;
}
public IMemberDefinition Resolve ()
{
return ResolveDefinition ();
}
protected abstract IMemberDefinition ResolveDefinition ();
public override string ToString ()
{
return FullName;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal interface IAssemblyResolver : IDisposable {
AssemblyDefinition Resolve (AssemblyNameReference name);
AssemblyDefinition Resolve (AssemblyNameReference name, ReaderParameters parameters);
}
internal interface IMetadataResolver {
TypeDefinition Resolve (TypeReference type);
FieldDefinition Resolve (FieldReference field);
MethodDefinition Resolve (MethodReference method);
}
#if !NET_CORE
[Serializable]
#endif
internal sealed class ResolutionException : Exception {
readonly MemberReference member;
public MemberReference Member {
get { return member; }
}
public IMetadataScope Scope {
get {
var type = member as TypeReference;
if (type != null)
return type.Scope;
var declaring_type = member.DeclaringType;
if (declaring_type != null)
return declaring_type.Scope;
throw new NotSupportedException ();
}
}
public ResolutionException (MemberReference member)
: base ("Failed to resolve " + member.FullName)
{
if (member == null)
throw new ArgumentNullException ("member");
this.member = member;
}
public ResolutionException (MemberReference member, Exception innerException)
: base ("Failed to resolve " + member.FullName, innerException)
{
if (member == null)
throw new ArgumentNullException ("member");
this.member = member;
}
#if !NET_CORE
ResolutionException (
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base (info, context)
{
}
#endif
}
internal class MetadataResolver : IMetadataResolver {
readonly IAssemblyResolver assembly_resolver;
public IAssemblyResolver AssemblyResolver {
get { return assembly_resolver; }
}
public MetadataResolver (IAssemblyResolver assemblyResolver)
{
if (assemblyResolver == null)
throw new ArgumentNullException ("assemblyResolver");
assembly_resolver = assemblyResolver;
}
public virtual TypeDefinition Resolve (TypeReference type)
{
Mixin.CheckType (type);
type = type.GetElementType ();
var scope = type.Scope;
if (scope == null)
return null;
switch (scope.MetadataScopeType) {
case MetadataScopeType.AssemblyNameReference:
var assembly = assembly_resolver.Resolve ((AssemblyNameReference) scope);
if (assembly == null)
return null;
return GetType (assembly.MainModule, type);
case MetadataScopeType.ModuleDefinition:
return GetType ((ModuleDefinition) scope, type);
case MetadataScopeType.ModuleReference:
var modules = type.Module.Assembly.Modules;
var module_ref = (ModuleReference) scope;
for (int i = 0; i < modules.Count; i++) {
var netmodule = modules [i];
if (netmodule.Name == module_ref.Name)
return GetType (netmodule, type);
}
break;
}
throw new NotSupportedException ();
}
static TypeDefinition GetType (ModuleDefinition module, TypeReference reference)
{
var type = GetTypeDefinition (module, reference);
if (type != null)
return type;
if (!module.HasExportedTypes)
return null;
var exported_types = module.ExportedTypes;
for (int i = 0; i < exported_types.Count; i++) {
var exported_type = exported_types [i];
if (exported_type.Name != reference.Name)
continue;
if (exported_type.Namespace != reference.Namespace)
continue;
return exported_type.Resolve ();
}
return null;
}
static TypeDefinition GetTypeDefinition (ModuleDefinition module, TypeReference type)
{
if (!type.IsNested)
return module.GetType (type.Namespace, type.Name);
var declaring_type = type.DeclaringType.Resolve ();
if (declaring_type == null)
return null;
return declaring_type.GetNestedType (type.TypeFullName ());
}
public virtual FieldDefinition Resolve (FieldReference field)
{
Mixin.CheckField (field);
var type = Resolve (field.DeclaringType);
if (type == null)
return null;
if (!type.HasFields)
return null;
return GetField (type, field);
}
FieldDefinition GetField (TypeDefinition type, FieldReference reference)
{
while (type != null) {
var field = GetField (type.Fields, reference);
if (field != null)
return field;
if (type.BaseType == null)
return null;
type = Resolve (type.BaseType);
}
return null;
}
static FieldDefinition GetField (Collection<FieldDefinition> fields, FieldReference reference)
{
for (int i = 0; i < fields.Count; i++) {
var field = fields [i];
if (field.Name != reference.Name)
continue;
if (!AreSame (field.FieldType, reference.FieldType))
continue;
return field;
}
return null;
}
public virtual MethodDefinition Resolve (MethodReference method)
{
Mixin.CheckMethod (method);
var type = Resolve (method.DeclaringType);
if (type == null)
return null;
method = method.GetElementMethod ();
if (!type.HasMethods)
return null;
return GetMethod (type, method);
}
MethodDefinition GetMethod (TypeDefinition type, MethodReference reference)
{
while (type != null) {
var method = GetMethod (type.Methods, reference);
if (method != null)
return method;
if (type.BaseType == null)
return null;
type = Resolve (type.BaseType);
}
return null;
}
public static MethodDefinition GetMethod (Collection<MethodDefinition> methods, MethodReference reference)
{
for (int i = 0; i < methods.Count; i++) {
var method = methods [i];
if (method.Name != reference.Name)
continue;
if (method.HasGenericParameters != reference.HasGenericParameters)
continue;
if (method.HasGenericParameters && method.GenericParameters.Count != reference.GenericParameters.Count)
continue;
if (!AreSame (method.ReturnType, reference.ReturnType))
continue;
if (method.IsVarArg () != reference.IsVarArg ())
continue;
if (method.IsVarArg () && IsVarArgCallTo (method, reference))
return method;
if (method.HasParameters != reference.HasParameters)
continue;
if (!method.HasParameters && !reference.HasParameters)
return method;
if (!AreSame (method.Parameters, reference.Parameters))
continue;
return method;
}
return null;
}
static bool AreSame (Collection<ParameterDefinition> a, Collection<ParameterDefinition> b)
{
var count = a.Count;
if (count != b.Count)
return false;
if (count == 0)
return true;
for (int i = 0; i < count; i++)
if (!AreSame (a [i].ParameterType, b [i].ParameterType))
return false;
return true;
}
static bool IsVarArgCallTo (MethodDefinition method, MethodReference reference)
{
if (method.Parameters.Count >= reference.Parameters.Count)
return false;
if (reference.GetSentinelPosition () != method.Parameters.Count)
return false;
for (int i = 0; i < method.Parameters.Count; i++)
if (!AreSame (method.Parameters [i].ParameterType, reference.Parameters [i].ParameterType))
return false;
return true;
}
static bool AreSame (TypeSpecification a, TypeSpecification b)
{
if (!AreSame (a.ElementType, b.ElementType))
return false;
if (a.IsGenericInstance)
return AreSame ((GenericInstanceType) a, (GenericInstanceType) b);
if (a.IsRequiredModifier || a.IsOptionalModifier)
return AreSame ((IModifierType) a, (IModifierType) b);
if (a.IsArray)
return AreSame ((ArrayType) a, (ArrayType) b);
return true;
}
static bool AreSame (ArrayType a, ArrayType b)
{
if (a.Rank != b.Rank)
return false;
// TODO: dimensions
return true;
}
static bool AreSame (IModifierType a, IModifierType b)
{
return AreSame (a.ModifierType, b.ModifierType);
}
static bool AreSame (GenericInstanceType a, GenericInstanceType b)
{
if (a.GenericArguments.Count != b.GenericArguments.Count)
return false;
for (int i = 0; i < a.GenericArguments.Count; i++)
if (!AreSame (a.GenericArguments [i], b.GenericArguments [i]))
return false;
return true;
}
static bool AreSame (GenericParameter a, GenericParameter b)
{
return a.Position == b.Position;
}
static bool AreSame (TypeReference a, TypeReference b)
{
if (ReferenceEquals (a, b))
return true;
if (a == null || b == null)
return false;
if (a.etype != b.etype)
return false;
if (a.IsGenericParameter)
return AreSame ((GenericParameter) a, (GenericParameter) b);
if (a.IsTypeSpecification ())
return AreSame ((TypeSpecification) a, (TypeSpecification) b);
if (a.Name != b.Name || a.Namespace != b.Namespace)
return false;
//TODO: check scope
return AreSame (a.DeclaringType, b.DeclaringType);
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Collections.Generic;
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
using Mono.Collections.Generic;
namespace Mono.Cecil {
struct Range {
public uint Start;
public uint Length;
public Range (uint index, uint length)
{
this.Start = index;
this.Length = length;
}
}
sealed class MetadataSystem {
internal AssemblyNameReference [] AssemblyReferences;
internal ModuleReference [] ModuleReferences;
internal TypeDefinition [] Types;
internal TypeReference [] TypeReferences;
internal FieldDefinition [] Fields;
internal MethodDefinition [] Methods;
internal MemberReference [] MemberReferences;
internal Dictionary<uint, Collection<uint>> NestedTypes;
internal Dictionary<uint, uint> ReverseNestedTypes;
internal Dictionary<uint, Collection<Row<uint, MetadataToken>>> Interfaces;
internal Dictionary<uint, Row<ushort, uint>> ClassLayouts;
internal Dictionary<uint, uint> FieldLayouts;
internal Dictionary<uint, uint> FieldRVAs;
internal Dictionary<MetadataToken, uint> FieldMarshals;
internal Dictionary<MetadataToken, Row<ElementType, uint>> Constants;
internal Dictionary<uint, Collection<MetadataToken>> Overrides;
internal Dictionary<MetadataToken, Range []> CustomAttributes;
internal Dictionary<MetadataToken, Range []> SecurityDeclarations;
internal Dictionary<uint, Range> Events;
internal Dictionary<uint, Range> Properties;
internal Dictionary<uint, Row<MethodSemanticsAttributes, MetadataToken>> Semantics;
internal Dictionary<uint, Row<PInvokeAttributes, uint, uint>> PInvokes;
internal Dictionary<MetadataToken, Range []> GenericParameters;
internal Dictionary<uint, Collection<MetadataToken>> GenericConstraints;
internal Document [] Documents;
internal Dictionary<uint, Collection<Row<uint, Range, Range, uint, uint, uint>>> LocalScopes;
internal ImportDebugInformation [] ImportScopes;
internal Dictionary<uint, uint> StateMachineMethods;
internal Dictionary<MetadataToken, Row<Guid, uint, uint> []> CustomDebugInformations;
static Dictionary<string, Row<ElementType, bool>> primitive_value_types;
static void InitializePrimitives ()
{
primitive_value_types = new Dictionary<string, Row<ElementType, bool>> (18, StringComparer.Ordinal) {
{ "Void", new Row<ElementType, bool> (ElementType.Void, false) },
{ "Boolean", new Row<ElementType, bool> (ElementType.Boolean, true) },
{ "Char", new Row<ElementType, bool> (ElementType.Char, true) },
{ "SByte", new Row<ElementType, bool> (ElementType.I1, true) },
{ "Byte", new Row<ElementType, bool> (ElementType.U1, true) },
{ "Int16", new Row<ElementType, bool> (ElementType.I2, true) },
{ "UInt16", new Row<ElementType, bool> (ElementType.U2, true) },
{ "Int32", new Row<ElementType, bool> (ElementType.I4, true) },
{ "UInt32", new Row<ElementType, bool> (ElementType.U4, true) },
{ "Int64", new Row<ElementType, bool> (ElementType.I8, true) },
{ "UInt64", new Row<ElementType, bool> (ElementType.U8, true) },
{ "Single", new Row<ElementType, bool> (ElementType.R4, true) },
{ "Double", new Row<ElementType, bool> (ElementType.R8, true) },
{ "String", new Row<ElementType, bool> (ElementType.String, false) },
{ "TypedReference", new Row<ElementType, bool> (ElementType.TypedByRef, false) },
{ "IntPtr", new Row<ElementType, bool> (ElementType.I, true) },
{ "UIntPtr", new Row<ElementType, bool> (ElementType.U, true) },
{ "Object", new Row<ElementType, bool> (ElementType.Object, false) },
};
}
public static void TryProcessPrimitiveTypeReference (TypeReference type)
{
if (type.Namespace != "System")
return;
var scope = type.scope;
if (scope == null || scope.MetadataScopeType != MetadataScopeType.AssemblyNameReference)
return;
Row<ElementType, bool> primitive_data;
if (!TryGetPrimitiveData (type, out primitive_data))
return;
type.etype = primitive_data.Col1;
type.IsValueType = primitive_data.Col2;
}
public static bool TryGetPrimitiveElementType (TypeDefinition type, out ElementType etype)
{
etype = ElementType.None;
if (type.Namespace != "System")
return false;
Row<ElementType, bool> primitive_data;
if (TryGetPrimitiveData (type, out primitive_data)) {
etype = primitive_data.Col1;
return true;
}
return false;
}
static bool TryGetPrimitiveData (TypeReference type, out Row<ElementType, bool> primitive_data)
{
if (primitive_value_types == null)
InitializePrimitives ();
return primitive_value_types.TryGetValue (type.Name, out primitive_data);
}
public void Clear ()
{
if (NestedTypes != null) NestedTypes = new Dictionary<uint, Collection<uint>> (capacity: 0);
if (ReverseNestedTypes != null) ReverseNestedTypes = new Dictionary<uint, uint> (capacity: 0);
if (Interfaces != null) Interfaces = new Dictionary<uint, Collection<Row<uint, MetadataToken>>> (capacity: 0);
if (ClassLayouts != null) ClassLayouts = new Dictionary<uint, Row<ushort, uint>> (capacity: 0);
if (FieldLayouts != null) FieldLayouts = new Dictionary<uint, uint> (capacity: 0);
if (FieldRVAs != null) FieldRVAs = new Dictionary<uint, uint> (capacity: 0);
if (FieldMarshals != null) FieldMarshals = new Dictionary<MetadataToken, uint> (capacity: 0);
if (Constants != null) Constants = new Dictionary<MetadataToken, Row<ElementType, uint>> (capacity: 0);
if (Overrides != null) Overrides = new Dictionary<uint, Collection<MetadataToken>> (capacity: 0);
if (CustomAttributes != null) CustomAttributes = new Dictionary<MetadataToken, Range []> (capacity: 0);
if (SecurityDeclarations != null) SecurityDeclarations = new Dictionary<MetadataToken, Range []> (capacity: 0);
if (Events != null) Events = new Dictionary<uint, Range> (capacity: 0);
if (Properties != null) Properties = new Dictionary<uint, Range> (capacity: 0);
if (Semantics != null) Semantics = new Dictionary<uint, Row<MethodSemanticsAttributes, MetadataToken>> (capacity: 0);
if (PInvokes != null) PInvokes = new Dictionary<uint, Row<PInvokeAttributes, uint, uint>> (capacity: 0);
if (GenericParameters != null) GenericParameters = new Dictionary<MetadataToken, Range []> (capacity: 0);
if (GenericConstraints != null) GenericConstraints = new Dictionary<uint, Collection<MetadataToken>> (capacity: 0);
Documents = Empty<Document>.Array;
ImportScopes = Empty<ImportDebugInformation>.Array;
if (LocalScopes != null) LocalScopes = new Dictionary<uint, Collection<Row<uint, Range, Range, uint, uint, uint>>> (capacity: 0);
if (StateMachineMethods != null) StateMachineMethods = new Dictionary<uint, uint> (capacity: 0);
}
public AssemblyNameReference GetAssemblyNameReference (uint rid)
{
if (rid < 1 || rid > AssemblyReferences.Length)
return null;
return AssemblyReferences [rid - 1];
}
public TypeDefinition GetTypeDefinition (uint rid)
{
if (rid < 1 || rid > Types.Length)
return null;
return Types [rid - 1];
}
public void AddTypeDefinition (TypeDefinition type)
{
Types [type.token.RID - 1] = type;
}
public TypeReference GetTypeReference (uint rid)
{
if (rid < 1 || rid > TypeReferences.Length)
return null;
return TypeReferences [rid - 1];
}
public void AddTypeReference (TypeReference type)
{
TypeReferences [type.token.RID - 1] = type;
}
public FieldDefinition GetFieldDefinition (uint rid)
{
if (rid < 1 || rid > Fields.Length)
return null;
return Fields [rid - 1];
}
public void AddFieldDefinition (FieldDefinition field)
{
Fields [field.token.RID - 1] = field;
}
public MethodDefinition GetMethodDefinition (uint rid)
{
if (rid < 1 || rid > Methods.Length)
return null;
return Methods [rid - 1];
}
public void AddMethodDefinition (MethodDefinition method)
{
Methods [method.token.RID - 1] = method;
}
public MemberReference GetMemberReference (uint rid)
{
if (rid < 1 || rid > MemberReferences.Length)
return null;
return MemberReferences [rid - 1];
}
public void AddMemberReference (MemberReference member)
{
MemberReferences [member.token.RID - 1] = member;
}
public bool TryGetNestedTypeMapping (TypeDefinition type, out Collection<uint> mapping)
{
return NestedTypes.TryGetValue (type.token.RID, out mapping);
}
public void SetNestedTypeMapping (uint type_rid, Collection<uint> mapping)
{
NestedTypes [type_rid] = mapping;
}
public void RemoveNestedTypeMapping (TypeDefinition type)
{
NestedTypes.Remove (type.token.RID);
}
public bool TryGetReverseNestedTypeMapping (TypeDefinition type, out uint declaring)
{
return ReverseNestedTypes.TryGetValue (type.token.RID, out declaring);
}
public void SetReverseNestedTypeMapping (uint nested, uint declaring)
{
ReverseNestedTypes [nested] = declaring;
}
public void RemoveReverseNestedTypeMapping (TypeDefinition type)
{
ReverseNestedTypes.Remove (type.token.RID);
}
public bool TryGetInterfaceMapping (TypeDefinition type, out Collection<Row<uint, MetadataToken>> mapping)
{
return Interfaces.TryGetValue (type.token.RID, out mapping);
}
public void SetInterfaceMapping (uint type_rid, Collection<Row<uint, MetadataToken>> mapping)
{
Interfaces [type_rid] = mapping;
}
public void RemoveInterfaceMapping (TypeDefinition type)
{
Interfaces.Remove (type.token.RID);
}
public void AddPropertiesRange (uint type_rid, Range range)
{
Properties.Add (type_rid, range);
}
public bool TryGetPropertiesRange (TypeDefinition type, out Range range)
{
return Properties.TryGetValue (type.token.RID, out range);
}
public void RemovePropertiesRange (TypeDefinition type)
{
Properties.Remove (type.token.RID);
}
public void AddEventsRange (uint type_rid, Range range)
{
Events.Add (type_rid, range);
}
public bool TryGetEventsRange (TypeDefinition type, out Range range)
{
return Events.TryGetValue (type.token.RID, out range);
}
public void RemoveEventsRange (TypeDefinition type)
{
Events.Remove (type.token.RID);
}
public bool TryGetGenericParameterRanges (IGenericParameterProvider owner, out Range [] ranges)
{
return GenericParameters.TryGetValue (owner.MetadataToken, out ranges);
}
public void RemoveGenericParameterRange (IGenericParameterProvider owner)
{
GenericParameters.Remove (owner.MetadataToken);
}
public bool TryGetCustomAttributeRanges (ICustomAttributeProvider owner, out Range [] ranges)
{
return CustomAttributes.TryGetValue (owner.MetadataToken, out ranges);
}
public void RemoveCustomAttributeRange (ICustomAttributeProvider owner)
{
CustomAttributes.Remove (owner.MetadataToken);
}
public bool TryGetSecurityDeclarationRanges (ISecurityDeclarationProvider owner, out Range [] ranges)
{
return SecurityDeclarations.TryGetValue (owner.MetadataToken, out ranges);
}
public void RemoveSecurityDeclarationRange (ISecurityDeclarationProvider owner)
{
SecurityDeclarations.Remove (owner.MetadataToken);
}
public bool TryGetGenericConstraintMapping (GenericParameter generic_parameter, out Collection<MetadataToken> mapping)
{
return GenericConstraints.TryGetValue (generic_parameter.token.RID, out mapping);
}
public void SetGenericConstraintMapping (uint gp_rid, Collection<MetadataToken> mapping)
{
GenericConstraints [gp_rid] = mapping;
}
public void RemoveGenericConstraintMapping (GenericParameter generic_parameter)
{
GenericConstraints.Remove (generic_parameter.token.RID);
}
public bool TryGetOverrideMapping (MethodDefinition method, out Collection<MetadataToken> mapping)
{
return Overrides.TryGetValue (method.token.RID, out mapping);
}
public void SetOverrideMapping (uint rid, Collection<MetadataToken> mapping)
{
Overrides [rid] = mapping;
}
public void RemoveOverrideMapping (MethodDefinition method)
{
Overrides.Remove (method.token.RID);
}
public Document GetDocument (uint rid)
{
if (rid < 1 || rid > Documents.Length)
return null;
return Documents [rid - 1];
}
public bool TryGetLocalScopes (MethodDefinition method, out Collection<Row<uint, Range, Range, uint, uint, uint>> scopes)
{
return LocalScopes.TryGetValue (method.MetadataToken.RID, out scopes);
}
public void SetLocalScopes (uint method_rid, Collection<Row<uint, Range, Range, uint, uint, uint>> records)
{
LocalScopes [method_rid] = records;
}
public ImportDebugInformation GetImportScope (uint rid)
{
if (rid < 1 || rid > ImportScopes.Length)
return null;
return ImportScopes [rid - 1];
}
public bool TryGetStateMachineKickOffMethod (MethodDefinition method, out uint rid)
{
return StateMachineMethods.TryGetValue (method.MetadataToken.RID, out rid);
}
public TypeDefinition GetFieldDeclaringType (uint field_rid)
{
return BinaryRangeSearch (Types, field_rid, true);
}
public TypeDefinition GetMethodDeclaringType (uint method_rid)
{
return BinaryRangeSearch (Types, method_rid, false);
}
static TypeDefinition BinaryRangeSearch (TypeDefinition [] types, uint rid, bool field)
{
int min = 0;
int max = types.Length - 1;
while (min <= max) {
int mid = min + ((max - min) / 2);
var type = types [mid];
var range = field ? type.fields_range : type.methods_range;
if (rid < range.Start)
max = mid - 1;
else if (rid >= range.Start + range.Length)
min = mid + 1;
else
return type;
}
return null;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
[Flags]
internal enum MethodAttributes : ushort {
MemberAccessMask = 0x0007,
CompilerControlled = 0x0000, // Member not referenceable
Private = 0x0001, // Accessible only by the parent type
FamANDAssem = 0x0002, // Accessible by sub-types only in this Assembly
Assembly = 0x0003, // Accessibly by anyone in the Assembly
Family = 0x0004, // Accessible only by type and sub-types
FamORAssem = 0x0005, // Accessibly by sub-types anywhere, plus anyone in assembly
Public = 0x0006, // Accessibly by anyone who has visibility to this scope
Static = 0x0010, // Defined on type, else per instance
Final = 0x0020, // Method may not be overridden
Virtual = 0x0040, // Method is virtual
HideBySig = 0x0080, // Method hides by name+sig, else just by name
VtableLayoutMask = 0x0100, // Use this mask to retrieve vtable attributes
ReuseSlot = 0x0000, // Method reuses existing slot in vtable
NewSlot = 0x0100, // Method always gets a new slot in the vtable
CheckAccessOnOverride = 0x0200, // Method can only be overriden if also accessible
Abstract = 0x0400, // Method does not provide an implementation
SpecialName = 0x0800, // Method is special
// Interop Attributes
PInvokeImpl = 0x2000, // Implementation is forwarded through PInvoke
UnmanagedExport = 0x0008, // Reserved: shall be zero for conforming implementations
// Additional flags
RTSpecialName = 0x1000, // CLI provides 'special' behavior, depending upon the name of the method
HasSecurity = 0x4000, // Method has security associate with it
RequireSecObject = 0x8000 // Method calls another method containing security code
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil {
internal enum MethodCallingConvention : byte {
Default = 0x0,
C = 0x1,
StdCall = 0x2,
ThisCall = 0x3,
FastCall = 0x4,
VarArg = 0x5,
Generic = 0x10,
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using RVA = System.UInt32;
namespace Mono.Cecil {
internal sealed class MethodDefinition : MethodReference, IMemberDefinition, ISecurityDeclarationProvider, ICustomDebugInformationProvider {
ushort attributes;
ushort impl_attributes;
internal volatile bool sem_attrs_ready;
internal MethodSemanticsAttributes sem_attrs;
Collection<CustomAttribute> custom_attributes;
Collection<SecurityDeclaration> security_declarations;
internal RVA rva;
internal PInvokeInfo pinvoke;
Collection<MethodReference> overrides;
internal MethodBody body;
internal MethodDebugInformation debug_info;
internal Collection<CustomDebugInformation> custom_infos;
public override string Name {
get { return base.Name; }
set {
if (IsWindowsRuntimeProjection && value != base.Name)
throw new InvalidOperationException ();
base.Name = value;
}
}
public MethodAttributes Attributes {
get { return (MethodAttributes) attributes; }
set {
if (IsWindowsRuntimeProjection && (ushort) value != attributes)
throw new InvalidOperationException ();
attributes = (ushort) value;
}
}
public MethodImplAttributes ImplAttributes {
get { return (MethodImplAttributes) impl_attributes; }
set {
if (IsWindowsRuntimeProjection && (ushort) value != impl_attributes)
throw new InvalidOperationException ();
impl_attributes = (ushort) value;
}
}
public MethodSemanticsAttributes SemanticsAttributes {
get {
if (sem_attrs_ready)
return sem_attrs;
if (HasImage) {
ReadSemantics ();
return sem_attrs;
}
sem_attrs = MethodSemanticsAttributes.None;
sem_attrs_ready = true;
return sem_attrs;
}
set { sem_attrs = value; }
}
internal new MethodDefinitionProjection WindowsRuntimeProjection {
get { return (MethodDefinitionProjection) projection; }
set { projection = value; }
}
internal void ReadSemantics ()
{
if (sem_attrs_ready)
return;
var module = this.Module;
if (module == null)
return;
if (!module.HasImage)
return;
module.Read (this, (method, reader) => reader.ReadAllSemantics (method));
}
public bool HasSecurityDeclarations {
get {
if (security_declarations != null)
return security_declarations.Count > 0;
return this.GetHasSecurityDeclarations (Module);
}
}
public Collection<SecurityDeclaration> SecurityDeclarations {
get { return security_declarations ?? (this.GetSecurityDeclarations (ref security_declarations, Module)); }
}
public bool HasCustomAttributes {
get {
if (custom_attributes != null)
return custom_attributes.Count > 0;
return this.GetHasCustomAttributes (Module);
}
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); }
}
public int RVA {
get { return (int) rva; }
}
public bool HasBody {
get {
return (attributes & (ushort) MethodAttributes.Abstract) == 0 &&
(attributes & (ushort) MethodAttributes.PInvokeImpl) == 0 &&
(impl_attributes & (ushort) MethodImplAttributes.InternalCall) == 0 &&
(impl_attributes & (ushort) MethodImplAttributes.Native) == 0 &&
(impl_attributes & (ushort) MethodImplAttributes.Unmanaged) == 0 &&
(impl_attributes & (ushort) MethodImplAttributes.Runtime) == 0;
}
}
public MethodBody Body {
get {
var local = this.body;
if (local != null)
return local;
if (!HasBody)
return null;
if (HasImage && rva != 0)
return Module.Read (ref body, this, (method, reader) => reader.ReadMethodBody (method));
return body = new MethodBody (this);
}
set {
var module = this.Module;
if (module == null) {
body = value;
return;
}
// we reset Body to null in ILSpy to save memory; so we need that operation to be thread-safe
lock (module.SyncRoot) {
body = value;
if (value == null)
this.debug_info = null;
}
}
}
public MethodDebugInformation DebugInformation {
get {
Mixin.Read (Body);
if (debug_info != null)
return debug_info;
return debug_info ?? (debug_info = new MethodDebugInformation (this));
}
}
public bool HasPInvokeInfo {
get {
if (pinvoke != null)
return true;
return IsPInvokeImpl;
}
}
public PInvokeInfo PInvokeInfo {
get {
if (pinvoke != null)
return pinvoke;
if (HasImage && IsPInvokeImpl)
return Module.Read (ref pinvoke, this, (method, reader) => reader.ReadPInvokeInfo (method));
return null;
}
set {
IsPInvokeImpl = true;
pinvoke = value;
}
}
public bool HasOverrides {
get {
if (overrides != null)
return overrides.Count > 0;
return HasImage && Module.Read (this, (method, reader) => reader.HasOverrides (method));
}
}
public Collection<MethodReference> Overrides {
get {
if (overrides != null)
return overrides;
if (HasImage)
return Module.Read (ref overrides, this, (method, reader) => reader.ReadOverrides (method));
return overrides = new Collection<MethodReference> ();
}
}
public override bool HasGenericParameters {
get {
if (generic_parameters != null)
return generic_parameters.Count > 0;
return this.GetHasGenericParameters (Module);
}
}
public override Collection<GenericParameter> GenericParameters {
get { return generic_parameters ?? (this.GetGenericParameters (ref generic_parameters, Module)); }
}
public bool HasCustomDebugInformations {
get {
Mixin.Read (Body);
return !custom_infos.IsNullOrEmpty ();
}
}
public Collection<CustomDebugInformation> CustomDebugInformations {
get {
Mixin.Read (Body);
return custom_infos ?? (custom_infos = new Collection<CustomDebugInformation> ());
}
}
#region MethodAttributes
public bool IsCompilerControlled {
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.CompilerControlled); }
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.CompilerControlled, value); }
}
public bool IsPrivate {
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Private); }
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Private, value); }
}
public bool IsFamilyAndAssembly {
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.FamANDAssem); }
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.FamANDAssem, value); }
}
public bool IsAssembly {
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Assembly); }
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Assembly, value); }
}
public bool IsFamily {
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Family); }
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Family, value); }
}
public bool IsFamilyOrAssembly {
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.FamORAssem); }
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.FamORAssem, value); }
}
public bool IsPublic {
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Public); }
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Public, value); }
}
public bool IsStatic {
get { return attributes.GetAttributes ((ushort) MethodAttributes.Static); }
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.Static, value); }
}
public bool IsFinal {
get { return attributes.GetAttributes ((ushort) MethodAttributes.Final); }
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.Final, value); }
}
public bool IsVirtual {
get { return attributes.GetAttributes ((ushort) MethodAttributes.Virtual); }
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.Virtual, value); }
}
public bool IsHideBySig {
get { return attributes.GetAttributes ((ushort) MethodAttributes.HideBySig); }
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.HideBySig, value); }
}
public bool IsReuseSlot {
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.VtableLayoutMask, (ushort) MethodAttributes.ReuseSlot); }
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.VtableLayoutMask, (ushort) MethodAttributes.ReuseSlot, value); }
}
public bool IsNewSlot {
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.VtableLayoutMask, (ushort) MethodAttributes.NewSlot); }
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.VtableLayoutMask, (ushort) MethodAttributes.NewSlot, value); }
}
public bool IsCheckAccessOnOverride {
get { return attributes.GetAttributes ((ushort) MethodAttributes.CheckAccessOnOverride); }
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.CheckAccessOnOverride, value); }
}
public bool IsAbstract {
get { return attributes.GetAttributes ((ushort) MethodAttributes.Abstract); }
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.Abstract, value); }
}
public bool IsSpecialName {
get { return attributes.GetAttributes ((ushort) MethodAttributes.SpecialName); }
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.SpecialName, value); }
}
public bool IsPInvokeImpl {
get { return attributes.GetAttributes ((ushort) MethodAttributes.PInvokeImpl); }
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.PInvokeImpl, value); }
}
public bool IsUnmanagedExport {
get { return attributes.GetAttributes ((ushort) MethodAttributes.UnmanagedExport); }
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.UnmanagedExport, value); }
}
public bool IsRuntimeSpecialName {
get { return attributes.GetAttributes ((ushort) MethodAttributes.RTSpecialName); }
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.RTSpecialName, value); }
}
public bool HasSecurity {
get { return attributes.GetAttributes ((ushort) MethodAttributes.HasSecurity); }
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.HasSecurity, value); }
}
#endregion
#region MethodImplAttributes
public bool IsIL {
get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.IL); }
set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.IL, value); }
}
public bool IsNative {
get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.Native); }
set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.Native, value); }
}
public bool IsRuntime {
get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.Runtime); }
set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.Runtime, value); }
}
public bool IsUnmanaged {
get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.ManagedMask, (ushort) MethodImplAttributes.Unmanaged); }
set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.ManagedMask, (ushort) MethodImplAttributes.Unmanaged, value); }
}
public bool IsManaged {
get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.ManagedMask, (ushort) MethodImplAttributes.Managed); }
set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.ManagedMask, (ushort) MethodImplAttributes.Managed, value); }
}
public bool IsForwardRef {
get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.ForwardRef); }
set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.ForwardRef, value); }
}
public bool IsPreserveSig {
get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.PreserveSig); }
set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.PreserveSig, value); }
}
public bool IsInternalCall {
get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.InternalCall); }
set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.InternalCall, value); }
}
public bool IsSynchronized {
get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.Synchronized); }
set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.Synchronized, value); }
}
public bool NoInlining {
get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.NoInlining); }
set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.NoInlining, value); }
}
public bool NoOptimization {
get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.NoOptimization); }
set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.NoOptimization, value); }
}
public bool AggressiveInlining {
get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.AggressiveInlining); }
set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.AggressiveInlining, value); }
}
#endregion
#region MethodSemanticsAttributes
public bool IsSetter {
get { return this.GetSemantics (MethodSemanticsAttributes.Setter); }
set { this.SetSemantics (MethodSemanticsAttributes.Setter, value); }
}
public bool IsGetter {
get { return this.GetSemantics (MethodSemanticsAttributes.Getter); }
set { this.SetSemantics (MethodSemanticsAttributes.Getter, value); }
}
public bool IsOther {
get { return this.GetSemantics (MethodSemanticsAttributes.Other); }
set { this.SetSemantics (MethodSemanticsAttributes.Other, value); }
}
public bool IsAddOn {
get { return this.GetSemantics (MethodSemanticsAttributes.AddOn); }
set { this.SetSemantics (MethodSemanticsAttributes.AddOn, value); }
}
public bool IsRemoveOn {
get { return this.GetSemantics (MethodSemanticsAttributes.RemoveOn); }
set { this.SetSemantics (MethodSemanticsAttributes.RemoveOn, value); }
}
public bool IsFire {
get { return this.GetSemantics (MethodSemanticsAttributes.Fire); }
set { this.SetSemantics (MethodSemanticsAttributes.Fire, value); }
}
#endregion
public new TypeDefinition DeclaringType {
get { return (TypeDefinition) base.DeclaringType; }
set { base.DeclaringType = value; }
}
public bool IsConstructor {
get {
return this.IsRuntimeSpecialName
&& this.IsSpecialName
&& (this.Name == ".cctor" || this.Name == ".ctor");
}
}
public override bool IsDefinition {
get { return true; }
}
internal MethodDefinition ()
{
this.token = new MetadataToken (TokenType.Method);
}
public MethodDefinition (string name, MethodAttributes attributes, TypeReference returnType)
: base (name, returnType)
{
this.attributes = (ushort) attributes;
this.HasThis = !this.IsStatic;
this.token = new MetadataToken (TokenType.Method);
}
public override MethodDefinition Resolve ()
{
return this;
}
}
static partial class Mixin {
public static ParameterDefinition GetParameter (this MethodBody self, int index)
{
var method = self.method;
if (method.HasThis) {
if (index == 0)
return self.ThisParameter;
index--;
}
var parameters = method.Parameters;
if (index < 0 || index >= parameters.size)
return null;
return parameters [index];
}
public static VariableDefinition GetVariable (this MethodBody self, int index)
{
var variables = self.Variables;
if (index < 0 || index >= variables.size)
return null;
return variables [index];
}
public static bool GetSemantics (this MethodDefinition self, MethodSemanticsAttributes semantics)
{
return (self.SemanticsAttributes & semantics) != 0;
}
public static void SetSemantics (this MethodDefinition self, MethodSemanticsAttributes semantics, bool value)
{
if (value)
self.SemanticsAttributes |= semantics;
else
self.SemanticsAttributes &= ~semantics;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
[Flags]
internal enum MethodImplAttributes : ushort {
CodeTypeMask = 0x0003,
IL = 0x0000, // Method impl is CIL
Native = 0x0001, // Method impl is native
OPTIL = 0x0002, // Reserved: shall be zero in conforming implementations
Runtime = 0x0003, // Method impl is provided by the runtime
ManagedMask = 0x0004, // Flags specifying whether the code is managed or unmanaged
Unmanaged = 0x0004, // Method impl is unmanaged, otherwise managed
Managed = 0x0000, // Method impl is managed
// Implementation info and interop
ForwardRef = 0x0010, // Indicates method is defined; used primarily in merge scenarios
PreserveSig = 0x0080, // Reserved: conforming implementations may ignore
InternalCall = 0x1000, // Reserved: shall be zero in conforming implementations
Synchronized = 0x0020, // Method is single threaded through the body
NoOptimization = 0x0040, // Method is not optimized by the JIT.
NoInlining = 0x0008, // Method may not be inlined
AggressiveInlining = 0x0100, // Method should be inlined, if possible.
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Text;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal class MethodReference : MemberReference, IMethodSignature, IGenericParameterProvider, IGenericContext {
internal ParameterDefinitionCollection parameters;
MethodReturnType return_type;
bool has_this;
bool explicit_this;
MethodCallingConvention calling_convention;
internal Collection<GenericParameter> generic_parameters;
public virtual bool HasThis {
get { return has_this; }
set { has_this = value; }
}
public virtual bool ExplicitThis {
get { return explicit_this; }
set { explicit_this = value; }
}
public virtual MethodCallingConvention CallingConvention {
get { return calling_convention; }
set { calling_convention = value; }
}
public virtual bool HasParameters {
get { return !parameters.IsNullOrEmpty (); }
}
public virtual Collection<ParameterDefinition> Parameters {
get {
if (parameters == null)
parameters = new ParameterDefinitionCollection (this);
return parameters;
}
}
IGenericParameterProvider IGenericContext.Type {
get {
var declaring_type = this.DeclaringType;
var instance = declaring_type as GenericInstanceType;
if (instance != null)
return instance.ElementType;
return declaring_type;
}
}
IGenericParameterProvider IGenericContext.Method {
get { return this; }
}
GenericParameterType IGenericParameterProvider.GenericParameterType {
get { return GenericParameterType.Method; }
}
public virtual bool HasGenericParameters {
get { return !generic_parameters.IsNullOrEmpty (); }
}
public virtual Collection<GenericParameter> GenericParameters {
get {
if (generic_parameters != null)
return generic_parameters;
return generic_parameters = new GenericParameterCollection (this);
}
}
public TypeReference ReturnType {
get {
var return_type = MethodReturnType;
return return_type != null ? return_type.ReturnType : null;
}
set {
var return_type = MethodReturnType;
if (return_type != null)
return_type.ReturnType = value;
}
}
public virtual MethodReturnType MethodReturnType {
get { return return_type; }
set { return_type = value; }
}
public override string FullName {
get {
var builder = new StringBuilder ();
builder.Append (ReturnType.FullName)
.Append (" ")
.Append (MemberFullName ());
this.MethodSignatureFullName (builder);
return builder.ToString ();
}
}
public virtual bool IsGenericInstance {
get { return false; }
}
public override bool ContainsGenericParameter {
get {
if (this.ReturnType.ContainsGenericParameter || base.ContainsGenericParameter)
return true;
if (!HasParameters)
return false;
var parameters = this.Parameters;
for (int i = 0; i < parameters.Count; i++)
if (parameters [i].ParameterType.ContainsGenericParameter)
return true;
return false;
}
}
internal MethodReference ()
{
this.return_type = new MethodReturnType (this);
this.token = new MetadataToken (TokenType.MemberRef);
}
public MethodReference (string name, TypeReference returnType)
: base (name)
{
Mixin.CheckType (returnType, Mixin.Argument.returnType);
this.return_type = new MethodReturnType (this);
this.return_type.ReturnType = returnType;
this.token = new MetadataToken (TokenType.MemberRef);
}
public MethodReference (string name, TypeReference returnType, TypeReference declaringType)
: this (name, returnType)
{
Mixin.CheckType (declaringType, Mixin.Argument.declaringType);
this.DeclaringType = declaringType;
}
public virtual MethodReference GetElementMethod ()
{
return this;
}
protected override IMemberDefinition ResolveDefinition ()
{
return this.Resolve ();
}
public new virtual MethodDefinition Resolve ()
{
var module = this.Module;
if (module == null)
throw new NotSupportedException ();
return module.Resolve (this);
}
}
static partial class Mixin {
public static bool IsVarArg (this IMethodSignature self)
{
return (self.CallingConvention & MethodCallingConvention.VarArg) != 0;
}
public static int GetSentinelPosition (this IMethodSignature self)
{
if (!self.HasParameters)
return -1;
var parameters = self.Parameters;
for (int i = 0; i < parameters.Count; i++)
if (parameters [i].ParameterType.IsSentinel)
return i;
return -1;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System.Threading;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal sealed class MethodReturnType : IConstantProvider, ICustomAttributeProvider, IMarshalInfoProvider {
internal IMethodSignature method;
internal ParameterDefinition parameter;
TypeReference return_type;
public IMethodSignature Method {
get { return method; }
}
public TypeReference ReturnType {
get { return return_type; }
set { return_type = value; }
}
internal ParameterDefinition Parameter {
get {
if (parameter == null)
Interlocked.CompareExchange (ref parameter, new ParameterDefinition (return_type, method), null);
return parameter;
}
}
public MetadataToken MetadataToken {
get { return Parameter.MetadataToken; }
set { Parameter.MetadataToken = value; }
}
public ParameterAttributes Attributes {
get { return Parameter.Attributes; }
set { Parameter.Attributes = value; }
}
public string Name {
get { return Parameter.Name; }
set { Parameter.Name = value; }
}
public bool HasCustomAttributes {
get { return parameter != null && parameter.HasCustomAttributes; }
}
public Collection<CustomAttribute> CustomAttributes {
get { return Parameter.CustomAttributes; }
}
public bool HasDefault {
get { return parameter != null && parameter.HasDefault; }
set { Parameter.HasDefault = value; }
}
public bool HasConstant {
get { return parameter != null && parameter.HasConstant; }
set { Parameter.HasConstant = value; }
}
public object Constant {
get { return Parameter.Constant; }
set { Parameter.Constant = value; }
}
public bool HasFieldMarshal {
get { return parameter != null && parameter.HasFieldMarshal; }
set { Parameter.HasFieldMarshal = value; }
}
public bool HasMarshalInfo {
get { return parameter != null && parameter.HasMarshalInfo; }
}
public MarshalInfo MarshalInfo {
get { return Parameter.MarshalInfo; }
set { Parameter.MarshalInfo = value; }
}
public MethodReturnType (IMethodSignature method)
{
this.method = method;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
[Flags]
internal enum MethodSemanticsAttributes : ushort {
None = 0x0000,
Setter = 0x0001, // Setter for property
Getter = 0x0002, // Getter for property
Other = 0x0004, // Other method for property or event
AddOn = 0x0008, // AddOn method for event
RemoveOn = 0x0010, // RemoveOn method for event
Fire = 0x0020 // Fire method for event
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal abstract class MethodSpecification : MethodReference {
readonly MethodReference method;
public MethodReference ElementMethod {
get { return method; }
}
public override string Name {
get { return method.Name; }
set { throw new InvalidOperationException (); }
}
public override MethodCallingConvention CallingConvention {
get { return method.CallingConvention; }
set { throw new InvalidOperationException (); }
}
public override bool HasThis {
get { return method.HasThis; }
set { throw new InvalidOperationException (); }
}
public override bool ExplicitThis {
get { return method.ExplicitThis; }
set { throw new InvalidOperationException (); }
}
public override MethodReturnType MethodReturnType {
get { return method.MethodReturnType; }
set { throw new InvalidOperationException (); }
}
public override TypeReference DeclaringType {
get { return method.DeclaringType; }
set { throw new InvalidOperationException (); }
}
public override ModuleDefinition Module {
get { return method.Module; }
}
public override bool HasParameters {
get { return method.HasParameters; }
}
public override Collection<ParameterDefinition> Parameters {
get { return method.Parameters; }
}
public override bool ContainsGenericParameter {
get { return method.ContainsGenericParameter; }
}
internal MethodSpecification (MethodReference method)
{
Mixin.CheckMethod (method);
this.method = method;
this.token = new MetadataToken (TokenType.MethodSpec);
}
public sealed override MethodReference GetElementMethod ()
{
return method.GetElementMethod ();
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using MD = Mono.Cecil.Metadata;
namespace Mono.Cecil {
internal interface IModifierType {
TypeReference ModifierType { get; }
TypeReference ElementType { get; }
}
internal sealed class OptionalModifierType : TypeSpecification, IModifierType {
TypeReference modifier_type;
public TypeReference ModifierType {
get { return modifier_type; }
set { modifier_type = value; }
}
public override string Name {
get { return base.Name + Suffix; }
}
public override string FullName {
get { return base.FullName + Suffix; }
}
string Suffix {
get { return " modopt(" + modifier_type + ")"; }
}
public override bool IsValueType {
get { return false; }
set { throw new InvalidOperationException (); }
}
public override bool IsOptionalModifier {
get { return true; }
}
public override bool ContainsGenericParameter {
get { return modifier_type.ContainsGenericParameter || base.ContainsGenericParameter; }
}
public OptionalModifierType (TypeReference modifierType, TypeReference type)
: base (type)
{
if (modifierType == null)
throw new ArgumentNullException (Mixin.Argument.modifierType.ToString ());
Mixin.CheckType (type);
this.modifier_type = modifierType;
this.etype = MD.ElementType.CModOpt;
}
}
internal sealed class RequiredModifierType : TypeSpecification, IModifierType {
TypeReference modifier_type;
public TypeReference ModifierType {
get { return modifier_type; }
set { modifier_type = value; }
}
public override string Name {
get { return base.Name + Suffix; }
}
public override string FullName {
get { return base.FullName + Suffix; }
}
string Suffix {
get { return " modreq(" + modifier_type + ")"; }
}
public override bool IsValueType {
get { return false; }
set { throw new InvalidOperationException (); }
}
public override bool IsRequiredModifier {
get { return true; }
}
public override bool ContainsGenericParameter {
get { return modifier_type.ContainsGenericParameter || base.ContainsGenericParameter; }
}
public RequiredModifierType (TypeReference modifierType, TypeReference type)
: base (type)
{
if (modifierType == null)
throw new ArgumentNullException (Mixin.Argument.modifierType.ToString ());
Mixin.CheckType (type);
this.modifier_type = modifierType;
this.etype = MD.ElementType.CModReqD;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using SR = System.Reflection;
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
using Mono.Cecil.PE;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal enum ReadingMode {
Immediate = 1,
Deferred = 2,
}
internal sealed class ReaderParameters {
ReadingMode reading_mode;
internal IAssemblyResolver assembly_resolver;
internal IMetadataResolver metadata_resolver;
#if !READ_ONLY
internal IMetadataImporterProvider metadata_importer_provider;
internal IReflectionImporterProvider reflection_importer_provider;
#endif
Stream symbol_stream;
ISymbolReaderProvider symbol_reader_provider;
bool read_symbols;
bool throw_symbols_mismatch;
bool projections;
bool in_memory;
bool read_write;
public ReadingMode ReadingMode {
get { return reading_mode; }
set { reading_mode = value; }
}
public bool InMemory {
get { return in_memory; }
set { in_memory = value; }
}
public IAssemblyResolver AssemblyResolver {
get { return assembly_resolver; }
set { assembly_resolver = value; }
}
public IMetadataResolver MetadataResolver {
get { return metadata_resolver; }
set { metadata_resolver = value; }
}
#if !READ_ONLY
public IMetadataImporterProvider MetadataImporterProvider {
get { return metadata_importer_provider; }
set { metadata_importer_provider = value; }
}
public IReflectionImporterProvider ReflectionImporterProvider {
get { return reflection_importer_provider; }
set { reflection_importer_provider = value; }
}
#endif
public Stream SymbolStream {
get { return symbol_stream; }
set { symbol_stream = value; }
}
public ISymbolReaderProvider SymbolReaderProvider {
get { return symbol_reader_provider; }
set { symbol_reader_provider = value; }
}
public bool ReadSymbols {
get { return read_symbols; }
set { read_symbols = value; }
}
public bool ThrowIfSymbolsAreNotMatching {
get { return throw_symbols_mismatch; }
set { throw_symbols_mismatch = value; }
}
public bool ReadWrite {
get { return read_write; }
set { read_write = value; }
}
public bool ApplyWindowsRuntimeProjections {
get { return projections; }
set { projections = value; }
}
public ReaderParameters ()
: this (ReadingMode.Deferred)
{
}
public ReaderParameters (ReadingMode readingMode)
{
this.reading_mode = readingMode;
this.throw_symbols_mismatch = true;
}
}
#if !READ_ONLY
internal sealed class ModuleParameters {
ModuleKind kind;
TargetRuntime runtime;
uint? timestamp;
TargetArchitecture architecture;
IAssemblyResolver assembly_resolver;
IMetadataResolver metadata_resolver;
#if !READ_ONLY
IMetadataImporterProvider metadata_importer_provider;
IReflectionImporterProvider reflection_importer_provider;
#endif
public ModuleKind Kind {
get { return kind; }
set { kind = value; }
}
public TargetRuntime Runtime {
get { return runtime; }
set { runtime = value; }
}
public uint? Timestamp {
get { return timestamp; }
set { timestamp = value; }
}
public TargetArchitecture Architecture {
get { return architecture; }
set { architecture = value; }
}
public IAssemblyResolver AssemblyResolver {
get { return assembly_resolver; }
set { assembly_resolver = value; }
}
public IMetadataResolver MetadataResolver {
get { return metadata_resolver; }
set { metadata_resolver = value; }
}
#if !READ_ONLY
public IMetadataImporterProvider MetadataImporterProvider {
get { return metadata_importer_provider; }
set { metadata_importer_provider = value; }
}
public IReflectionImporterProvider ReflectionImporterProvider {
get { return reflection_importer_provider; }
set { reflection_importer_provider = value; }
}
#endif
public ModuleParameters ()
{
this.kind = ModuleKind.Dll;
this.Runtime = GetCurrentRuntime ();
this.architecture = TargetArchitecture.I386;
}
static TargetRuntime GetCurrentRuntime ()
{
#if !NET_CORE
return typeof (object).Assembly.ImageRuntimeVersion.ParseRuntime ();
#else
var corlib_name = AssemblyNameReference.Parse (typeof (object).Assembly ().FullName);
var corlib_version = corlib_name.Version;
switch (corlib_version.Major) {
case 1:
return corlib_version.Minor == 0
? TargetRuntime.Net_1_0
: TargetRuntime.Net_1_1;
case 2:
return TargetRuntime.Net_2_0;
case 4:
return TargetRuntime.Net_4_0;
default:
throw new NotSupportedException ();
}
#endif
}
}
internal sealed class WriterParameters {
uint? timestamp;
Stream symbol_stream;
ISymbolWriterProvider symbol_writer_provider;
bool write_symbols;
#if !NET_CORE
SR.StrongNameKeyPair key_pair;
#endif
public uint? Timestamp {
get { return timestamp; }
set { timestamp = value; }
}
public Stream SymbolStream {
get { return symbol_stream; }
set { symbol_stream = value; }
}
public ISymbolWriterProvider SymbolWriterProvider {
get { return symbol_writer_provider; }
set { symbol_writer_provider = value; }
}
public bool WriteSymbols {
get { return write_symbols; }
set { write_symbols = value; }
}
#if !NET_CORE
public SR.StrongNameKeyPair StrongNameKeyPair {
get { return key_pair; }
set { key_pair = value; }
}
#endif
}
#endif
internal sealed class ModuleDefinition : ModuleReference, ICustomAttributeProvider, ICustomDebugInformationProvider, IDisposable {
internal Image Image;
internal MetadataSystem MetadataSystem;
internal ReadingMode ReadingMode;
internal ISymbolReaderProvider SymbolReaderProvider;
internal ISymbolReader symbol_reader;
internal Disposable<IAssemblyResolver> assembly_resolver;
internal IMetadataResolver metadata_resolver;
internal TypeSystem type_system;
internal readonly MetadataReader reader;
readonly string file_name;
internal string runtime_version;
internal ModuleKind kind;
WindowsRuntimeProjections projections;
MetadataKind metadata_kind;
TargetRuntime runtime;
TargetArchitecture architecture;
ModuleAttributes attributes;
ModuleCharacteristics characteristics;
internal ushort linker_version = 8;
Guid mvid;
internal uint timestamp;
internal AssemblyDefinition assembly;
MethodDefinition entry_point;
#if !READ_ONLY
internal IReflectionImporter reflection_importer;
internal IMetadataImporter metadata_importer;
#endif
Collection<CustomAttribute> custom_attributes;
Collection<AssemblyNameReference> references;
Collection<ModuleReference> modules;
Collection<Resource> resources;
Collection<ExportedType> exported_types;
TypeDefinitionCollection types;
internal Collection<CustomDebugInformation> custom_infos;
public bool IsMain {
get { return kind != ModuleKind.NetModule; }
}
public ModuleKind Kind {
get { return kind; }
set { kind = value; }
}
public MetadataKind MetadataKind {
get { return metadata_kind; }
set { metadata_kind = value; }
}
internal WindowsRuntimeProjections Projections {
get {
if (projections == null)
Interlocked.CompareExchange (ref projections, new WindowsRuntimeProjections (this), null);
return projections;
}
}
public TargetRuntime Runtime {
get { return runtime; }
set {
runtime = value;
runtime_version = runtime.RuntimeVersionString ();
}
}
public string RuntimeVersion {
get { return runtime_version; }
set {
runtime_version = value;
runtime = runtime_version.ParseRuntime ();
}
}
public TargetArchitecture Architecture {
get { return architecture; }
set { architecture = value; }
}
public ModuleAttributes Attributes {
get { return attributes; }
set { attributes = value; }
}
public ModuleCharacteristics Characteristics {
get { return characteristics; }
set { characteristics = value; }
}
[Obsolete ("Use FileName")]
public string FullyQualifiedName {
get { return file_name; }
}
public string FileName {
get { return file_name; }
}
public Guid Mvid {
get { return mvid; }
set { mvid = value; }
}
internal bool HasImage {
get { return Image != null; }
}
public bool HasSymbols {
get { return symbol_reader != null; }
}
public ISymbolReader SymbolReader {
get { return symbol_reader; }
}
public override MetadataScopeType MetadataScopeType {
get { return MetadataScopeType.ModuleDefinition; }
}
public AssemblyDefinition Assembly {
get { return assembly; }
}
#if !READ_ONLY
internal IReflectionImporter ReflectionImporter {
get {
if (reflection_importer == null)
Interlocked.CompareExchange (ref reflection_importer, new DefaultReflectionImporter (this), null);
return reflection_importer;
}
}
internal IMetadataImporter MetadataImporter {
get {
if (metadata_importer == null)
Interlocked.CompareExchange (ref metadata_importer, new DefaultMetadataImporter (this), null);
return metadata_importer;
}
}
#endif
public IAssemblyResolver AssemblyResolver {
get {
if (assembly_resolver.value == null) {
lock (module_lock) {
assembly_resolver = Disposable.Owned (new DefaultAssemblyResolver () as IAssemblyResolver);
}
}
return assembly_resolver.value;
}
}
public IMetadataResolver MetadataResolver {
get {
if (metadata_resolver == null)
Interlocked.CompareExchange (ref metadata_resolver, new MetadataResolver (this.AssemblyResolver), null);
return metadata_resolver;
}
}
public TypeSystem TypeSystem {
get {
if (type_system == null)
Interlocked.CompareExchange (ref type_system, TypeSystem.CreateTypeSystem (this), null);
return type_system;
}
}
public bool HasAssemblyReferences {
get {
if (references != null)
return references.Count > 0;
return HasImage && Image.HasTable (Table.AssemblyRef);
}
}
public Collection<AssemblyNameReference> AssemblyReferences {
get {
if (references != null)
return references;
if (HasImage)
return Read (ref references, this, (_, reader) => reader.ReadAssemblyReferences ());
return references = new Collection<AssemblyNameReference> ();
}
}
public bool HasModuleReferences {
get {
if (modules != null)
return modules.Count > 0;
return HasImage && Image.HasTable (Table.ModuleRef);
}
}
public Collection<ModuleReference> ModuleReferences {
get {
if (modules != null)
return modules;
if (HasImage)
return Read (ref modules, this, (_, reader) => reader.ReadModuleReferences ());
return modules = new Collection<ModuleReference> ();
}
}
public bool HasResources {
get {
if (resources != null)
return resources.Count > 0;
if (HasImage)
return Image.HasTable (Table.ManifestResource) || Read (this, (_, reader) => reader.HasFileResource ());
return false;
}
}
public Collection<Resource> Resources {
get {
if (resources != null)
return resources;
if (HasImage)
return Read (ref resources, this, (_, reader) => reader.ReadResources ());
return resources = new Collection<Resource> ();
}
}
public bool HasCustomAttributes {
get {
if (custom_attributes != null)
return custom_attributes.Count > 0;
return this.GetHasCustomAttributes (this);
}
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, this)); }
}
public bool HasTypes {
get {
if (types != null)
return types.Count > 0;
return HasImage && Image.HasTable (Table.TypeDef);
}
}
public Collection<TypeDefinition> Types {
get {
if (types != null)
return types;
if (HasImage)
return Read (ref types, this, (_, reader) => reader.ReadTypes ());
return types = new TypeDefinitionCollection (this);
}
}
public bool HasExportedTypes {
get {
if (exported_types != null)
return exported_types.Count > 0;
return HasImage && Image.HasTable (Table.ExportedType);
}
}
public Collection<ExportedType> ExportedTypes {
get {
if (exported_types != null)
return exported_types;
if (HasImage)
return Read (ref exported_types, this, (_, reader) => reader.ReadExportedTypes ());
return exported_types = new Collection<ExportedType> ();
}
}
public MethodDefinition EntryPoint {
get {
if (entry_point != null)
return entry_point;
if (HasImage)
return Read (ref entry_point, this, (_, reader) => reader.ReadEntryPoint ());
return entry_point = null;
}
set { entry_point = value; }
}
public bool HasCustomDebugInformations {
get {
return custom_infos != null && custom_infos.Count > 0;
}
}
public Collection<CustomDebugInformation> CustomDebugInformations {
get {
return custom_infos ?? (custom_infos = new Collection<CustomDebugInformation> ());
}
}
internal ModuleDefinition ()
{
this.MetadataSystem = new MetadataSystem ();
this.token = new MetadataToken (TokenType.Module, 1);
}
internal ModuleDefinition (Image image)
: this ()
{
this.Image = image;
this.kind = image.Kind;
this.RuntimeVersion = image.RuntimeVersion;
this.architecture = image.Architecture;
this.attributes = image.Attributes;
this.characteristics = image.Characteristics;
this.linker_version = image.LinkerVersion;
this.file_name = image.FileName;
this.timestamp = image.Timestamp;
this.reader = new MetadataReader (this);
}
public void Dispose ()
{
if (Image != null)
Image.Dispose ();
if (symbol_reader != null)
symbol_reader.Dispose ();
if (assembly_resolver.value != null)
assembly_resolver.Dispose ();
}
public bool HasTypeReference (string fullName)
{
return HasTypeReference (string.Empty, fullName);
}
public bool HasTypeReference (string scope, string fullName)
{
Mixin.CheckFullName (fullName);
if (!HasImage)
return false;
return GetTypeReference (scope, fullName) != null;
}
public bool TryGetTypeReference (string fullName, out TypeReference type)
{
return TryGetTypeReference (string.Empty, fullName, out type);
}
public bool TryGetTypeReference (string scope, string fullName, out TypeReference type)
{
Mixin.CheckFullName (fullName);
if (!HasImage) {
type = null;
return false;
}
return (type = GetTypeReference (scope, fullName)) != null;
}
TypeReference GetTypeReference (string scope, string fullname)
{
return Read (new Row<string, string> (scope, fullname), (row, reader) => reader.GetTypeReference (row.Col1, row.Col2));
}
public IEnumerable<TypeReference> GetTypeReferences ()
{
if (!HasImage)
return Empty<TypeReference>.Array;
return Read (this, (_, reader) => reader.GetTypeReferences ());
}
public IEnumerable<MemberReference> GetMemberReferences ()
{
if (!HasImage)
return Empty<MemberReference>.Array;
return Read (this, (_, reader) => reader.GetMemberReferences ());
}
public IEnumerable<CustomAttribute> GetCustomAttributes ()
{
if (!HasImage)
return Empty<CustomAttribute>.Array;
return Read (this, (_, reader) => reader.GetCustomAttributes ());
}
public TypeReference GetType (string fullName, bool runtimeName)
{
return runtimeName
? TypeParser.ParseType (this, fullName, typeDefinitionOnly: true)
: GetType (fullName);
}
public TypeDefinition GetType (string fullName)
{
Mixin.CheckFullName (fullName);
var position = fullName.IndexOf ('/');
if (position > 0)
return GetNestedType (fullName);
return ((TypeDefinitionCollection) this.Types).GetType (fullName);
}
public TypeDefinition GetType (string @namespace, string name)
{
Mixin.CheckName (name);
return ((TypeDefinitionCollection) this.Types).GetType (@namespace ?? string.Empty, name);
}
public IEnumerable<TypeDefinition> GetTypes ()
{
return GetTypes (Types);
}
static IEnumerable<TypeDefinition> GetTypes (Collection<TypeDefinition> types)
{
for (int i = 0; i < types.Count; i++) {
var type = types [i];
yield return type;
if (!type.HasNestedTypes)
continue;
foreach (var nested in GetTypes (type.NestedTypes))
yield return nested;
}
}
TypeDefinition GetNestedType (string fullname)
{
var names = fullname.Split ('/');
var type = GetType (names [0]);
if (type == null)
return null;
for (int i = 1; i < names.Length; i++) {
var nested_type = type.GetNestedType (names [i]);
if (nested_type == null)
return null;
type = nested_type;
}
return type;
}
internal FieldDefinition Resolve (FieldReference field)
{
return MetadataResolver.Resolve (field);
}
internal MethodDefinition Resolve (MethodReference method)
{
return MetadataResolver.Resolve (method);
}
internal TypeDefinition Resolve (TypeReference type)
{
return MetadataResolver.Resolve (type);
}
#if !READ_ONLY
static void CheckContext (IGenericParameterProvider context, ModuleDefinition module)
{
if (context == null)
return;
if (context.Module != module)
throw new ArgumentException ();
}
[Obsolete ("Use ImportReference", error: false)]
public TypeReference Import (Type type)
{
return ImportReference (type, null);
}
public TypeReference ImportReference (Type type)
{
return ImportReference (type, null);
}
[Obsolete ("Use ImportReference", error: false)]
public TypeReference Import (Type type, IGenericParameterProvider context)
{
return ImportReference (type, context);
}
public TypeReference ImportReference (Type type, IGenericParameterProvider context)
{
Mixin.CheckType (type);
CheckContext (context, this);
return ReflectionImporter.ImportReference (type, context);
}
[Obsolete ("Use ImportReference", error: false)]
public FieldReference Import (SR.FieldInfo field)
{
return ImportReference (field, null);
}
[Obsolete ("Use ImportReference", error: false)]
public FieldReference Import (SR.FieldInfo field, IGenericParameterProvider context)
{
return ImportReference (field, context);
}
public FieldReference ImportReference (SR.FieldInfo field)
{
return ImportReference (field, null);
}
public FieldReference ImportReference (SR.FieldInfo field, IGenericParameterProvider context)
{
Mixin.CheckField (field);
CheckContext (context, this);
return ReflectionImporter.ImportReference (field, context);
}
[Obsolete ("Use ImportReference", error: false)]
public MethodReference Import (SR.MethodBase method)
{
return ImportReference (method, null);
}
[Obsolete ("Use ImportReference", error: false)]
public MethodReference Import (SR.MethodBase method, IGenericParameterProvider context)
{
return ImportReference (method, context);
}
public MethodReference ImportReference (SR.MethodBase method)
{
return ImportReference (method, null);
}
public MethodReference ImportReference (SR.MethodBase method, IGenericParameterProvider context)
{
Mixin.CheckMethod (method);
CheckContext (context, this);
return ReflectionImporter.ImportReference (method, context);
}
[Obsolete ("Use ImportReference", error: false)]
public TypeReference Import (TypeReference type)
{
return ImportReference (type, null);
}
[Obsolete ("Use ImportReference", error: false)]
public TypeReference Import (TypeReference type, IGenericParameterProvider context)
{
return ImportReference (type, context);
}
public TypeReference ImportReference (TypeReference type)
{
return ImportReference (type, null);
}
public TypeReference ImportReference (TypeReference type, IGenericParameterProvider context)
{
Mixin.CheckType (type);
if (type.Module == this)
return type;
CheckContext (context, this);
return MetadataImporter.ImportReference (type, context);
}
[Obsolete ("Use ImportReference", error: false)]
public FieldReference Import (FieldReference field)
{
return ImportReference (field, null);
}
[Obsolete ("Use ImportReference", error: false)]
public FieldReference Import (FieldReference field, IGenericParameterProvider context)
{
return ImportReference (field, context);
}
public FieldReference ImportReference (FieldReference field)
{
return ImportReference (field, null);
}
public FieldReference ImportReference (FieldReference field, IGenericParameterProvider context)
{
Mixin.CheckField (field);
if (field.Module == this)
return field;
CheckContext (context, this);
return MetadataImporter.ImportReference (field, context);
}
[Obsolete ("Use ImportReference", error: false)]
public MethodReference Import (MethodReference method)
{
return ImportReference (method, null);
}
[Obsolete ("Use ImportReference", error: false)]
public MethodReference Import (MethodReference method, IGenericParameterProvider context)
{
return ImportReference (method, context);
}
public MethodReference ImportReference (MethodReference method)
{
return ImportReference (method, null);
}
public MethodReference ImportReference (MethodReference method, IGenericParameterProvider context)
{
Mixin.CheckMethod (method);
if (method.Module == this)
return method;
CheckContext (context, this);
return MetadataImporter.ImportReference (method, context);
}
#endif
public IMetadataTokenProvider LookupToken (int token)
{
return LookupToken (new MetadataToken ((uint) token));
}
public IMetadataTokenProvider LookupToken (MetadataToken token)
{
return Read (token, (t, reader) => reader.LookupToken (t));
}
readonly object module_lock = new object();
internal object SyncRoot {
get { return module_lock; }
}
internal void Read<TItem> (TItem item, Action<TItem, MetadataReader> read)
{
lock (module_lock) {
var position = reader.position;
var context = reader.context;
read (item, reader);
reader.position = position;
reader.context = context;
}
}
internal TRet Read<TItem, TRet> (TItem item, Func<TItem, MetadataReader, TRet> read)
{
lock (module_lock) {
var position = reader.position;
var context = reader.context;
var ret = read (item, reader);
reader.position = position;
reader.context = context;
return ret;
}
}
internal TRet Read<TItem, TRet> (ref TRet variable, TItem item, Func<TItem, MetadataReader, TRet> read) where TRet : class
{
lock (module_lock) {
if (variable != null)
return variable;
var position = reader.position;
var context = reader.context;
var ret = read (item, reader);
reader.position = position;
reader.context = context;
return variable = ret;
}
}
public bool HasDebugHeader {
get { return Image != null && Image.DebugHeader != null; }
}
public ImageDebugHeader GetDebugHeader ()
{
return Image.DebugHeader ?? new ImageDebugHeader ();
}
#if !READ_ONLY
public static ModuleDefinition CreateModule (string name, ModuleKind kind)
{
return CreateModule (name, new ModuleParameters { Kind = kind });
}
public static ModuleDefinition CreateModule (string name, ModuleParameters parameters)
{
Mixin.CheckName (name);
Mixin.CheckParameters (parameters);
var module = new ModuleDefinition {
Name = name,
kind = parameters.Kind,
timestamp = parameters.Timestamp ?? Mixin.GetTimestamp (),
Runtime = parameters.Runtime,
architecture = parameters.Architecture,
mvid = Guid.NewGuid (),
Attributes = ModuleAttributes.ILOnly,
Characteristics = (ModuleCharacteristics) 0x8540,
};
if (parameters.AssemblyResolver != null)
module.assembly_resolver = Disposable.NotOwned (parameters.AssemblyResolver);
if (parameters.MetadataResolver != null)
module.metadata_resolver = parameters.MetadataResolver;
#if !READ_ONLY
if (parameters.MetadataImporterProvider != null)
module.metadata_importer = parameters.MetadataImporterProvider.GetMetadataImporter (module);
if (parameters.ReflectionImporterProvider != null)
module.reflection_importer = parameters.ReflectionImporterProvider.GetReflectionImporter (module);
#endif
if (parameters.Kind != ModuleKind.NetModule) {
var assembly = new AssemblyDefinition ();
module.assembly = assembly;
module.assembly.Name = CreateAssemblyName (name);
assembly.main_module = module;
}
module.Types.Add (new TypeDefinition (string.Empty, "<Module>", TypeAttributes.NotPublic));
return module;
}
static AssemblyNameDefinition CreateAssemblyName (string name)
{
if (name.EndsWith (".dll") || name.EndsWith (".exe"))
name = name.Substring (0, name.Length - 4);
return new AssemblyNameDefinition (name, Mixin.ZeroVersion);
}
#endif
public void ReadSymbols ()
{
if (string.IsNullOrEmpty (file_name))
throw new InvalidOperationException ();
var provider = new DefaultSymbolReaderProvider (throwIfNoSymbol: true);
ReadSymbols (provider.GetSymbolReader (this, file_name), throwIfSymbolsAreNotMaching: true);
}
public void ReadSymbols (ISymbolReader reader)
{
ReadSymbols(reader, throwIfSymbolsAreNotMaching: true);
}
public void ReadSymbols (ISymbolReader reader, bool throwIfSymbolsAreNotMaching)
{
if (reader == null)
throw new ArgumentNullException ("reader");
symbol_reader = reader;
if (!symbol_reader.ProcessDebugHeader (GetDebugHeader ())) {
symbol_reader = null;
if (throwIfSymbolsAreNotMaching)
throw new SymbolsNotMatchingException ("Symbols were found but are not matching the assembly");
return;
}
if (HasImage && ReadingMode == ReadingMode.Immediate) {
var immediate_reader = new ImmediateModuleReader (Image);
immediate_reader.ReadSymbols (this);
}
}
public static ModuleDefinition ReadModule (string fileName)
{
return ReadModule (fileName, new ReaderParameters (ReadingMode.Deferred));
}
public static ModuleDefinition ReadModule (string fileName, ReaderParameters parameters)
{
var stream = GetFileStream (fileName, FileMode.Open, parameters.ReadWrite ? FileAccess.ReadWrite : FileAccess.Read, FileShare.Read);
if (parameters.InMemory) {
var memory = new MemoryStream (stream.CanSeek ? (int) stream.Length : 0);
using (stream)
stream.CopyTo (memory);
memory.Position = 0;
stream = memory;
}
try {
return ReadModule (Disposable.Owned (stream), fileName, parameters);
} catch (Exception) {
stream.Dispose ();
throw;
}
}
static Stream GetFileStream (string fileName, FileMode mode, FileAccess access, FileShare share)
{
Mixin.CheckFileName (fileName);
return new FileStream (fileName, mode, access, share);
}
public static ModuleDefinition ReadModule (Stream stream)
{
return ReadModule (stream, new ReaderParameters (ReadingMode.Deferred));
}
public static ModuleDefinition ReadModule (Stream stream, ReaderParameters parameters)
{
Mixin.CheckStream (stream);
Mixin.CheckReadSeek (stream);
return ReadModule (Disposable.NotOwned (stream), stream.GetFileName (), parameters);
}
static ModuleDefinition ReadModule (Disposable<Stream> stream, string fileName, ReaderParameters parameters)
{
Mixin.CheckParameters (parameters);
return ModuleReader.CreateModule (
ImageReader.ReadImage (stream, fileName),
parameters);
}
#if !READ_ONLY
public void Write (string fileName)
{
Write (fileName, new WriterParameters ());
}
public void Write (string fileName, WriterParameters parameters)
{
Mixin.CheckParameters (parameters);
var file = GetFileStream (fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read);
ModuleWriter.WriteModule (this, Disposable.Owned (file), parameters);
}
public void Write ()
{
Write (new WriterParameters ());
}
public void Write (WriterParameters parameters)
{
if (!HasImage)
throw new InvalidOperationException ();
Write (Image.Stream.value, parameters);
}
public void Write (Stream stream)
{
Write (stream, new WriterParameters ());
}
public void Write (Stream stream, WriterParameters parameters)
{
Mixin.CheckStream (stream);
Mixin.CheckWriteSeek (stream);
Mixin.CheckParameters (parameters);
ModuleWriter.WriteModule (this, Disposable.NotOwned (stream), parameters);
}
#endif
}
static partial class Mixin {
internal enum Argument {
name,
fileName,
fullName,
stream,
type,
method,
field,
parameters,
module,
modifierType,
eventType,
fieldType,
declaringType,
returnType,
propertyType,
interfaceType,
}
public static void CheckName (object name)
{
if (name == null)
throw new ArgumentNullException (Argument.name.ToString ());
}
public static void CheckName (string name)
{
if (string.IsNullOrEmpty (name))
throw new ArgumentNullOrEmptyException (Argument.name.ToString ());
}
public static void CheckFileName (string fileName)
{
if (string.IsNullOrEmpty (fileName))
throw new ArgumentNullOrEmptyException (Argument.fileName.ToString ());
}
public static void CheckFullName (string fullName)
{
if (string.IsNullOrEmpty (fullName))
throw new ArgumentNullOrEmptyException (Argument.fullName.ToString ());
}
public static void CheckStream (object stream)
{
if (stream == null)
throw new ArgumentNullException (Argument.stream.ToString ());
}
public static void CheckWriteSeek (Stream stream)
{
if (!stream.CanWrite || !stream.CanSeek)
throw new ArgumentException ("Stream must be writable and seekable.");
}
public static void CheckReadSeek (Stream stream)
{
if (!stream.CanRead || !stream.CanSeek)
throw new ArgumentException ("Stream must be readable and seekable.");
}
public static void CheckType (object type)
{
if (type == null)
throw new ArgumentNullException (Argument.type.ToString ());
}
public static void CheckType (object type, Argument argument)
{
if (type == null)
throw new ArgumentNullException (argument.ToString ());
}
public static void CheckField (object field)
{
if (field == null)
throw new ArgumentNullException (Argument.field.ToString ());
}
public static void CheckMethod (object method)
{
if (method == null)
throw new ArgumentNullException (Argument.method.ToString ());
}
public static void CheckParameters (object parameters)
{
if (parameters == null)
throw new ArgumentNullException (Argument.parameters.ToString ());
}
public static uint GetTimestamp ()
{
return (uint) DateTime.UtcNow.Subtract (new DateTime (1970, 1, 1)).TotalSeconds;
}
public static bool HasImage (this ModuleDefinition self)
{
return self != null && self.HasImage;
}
public static string GetFileName (this Stream self)
{
var file_stream = self as FileStream;
if (file_stream == null)
return string.Empty;
return Path.GetFullPath (file_stream.Name);
}
#if !NET_4_0
public static void CopyTo (this Stream self, Stream target)
{
var buffer = new byte [1024 * 8];
int read;
while ((read = self.Read (buffer, 0, buffer.Length)) > 0)
target.Write (buffer, 0, read);
}
#endif
public static TargetRuntime ParseRuntime (this string self)
{
if (string.IsNullOrEmpty (self))
return TargetRuntime.Net_4_0;
switch (self [1]) {
case '1':
return self [3] == '0'
? TargetRuntime.Net_1_0
: TargetRuntime.Net_1_1;
case '2':
return TargetRuntime.Net_2_0;
case '4':
default:
return TargetRuntime.Net_4_0;
}
}
public static string RuntimeVersionString (this TargetRuntime runtime)
{
switch (runtime) {
case TargetRuntime.Net_1_0:
return "v1.0.3705";
case TargetRuntime.Net_1_1:
return "v1.1.4322";
case TargetRuntime.Net_2_0:
return "v2.0.50727";
case TargetRuntime.Net_4_0:
default:
return "v4.0.30319";
}
}
public static bool IsWindowsMetadata (this ModuleDefinition module)
{
return module.MetadataKind != MetadataKind.Ecma335;
}
public static byte [] ReadAll (this Stream self)
{
int read;
var memory = new MemoryStream ((int) self.Length);
var buffer = new byte [1024];
while ((read = self.Read (buffer, 0, buffer.Length)) != 0)
memory.Write (buffer, 0, read);
return memory.ToArray ();
}
public static void Read (object o)
{
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
internal enum ModuleKind {
Dll,
Console,
Windows,
NetModule,
}
internal enum MetadataKind {
Ecma335,
WindowsMetadata,
ManagedWindowsMetadata,
}
internal enum TargetArchitecture {
I386 = 0x014c,
AMD64 = 0x8664,
IA64 = 0x0200,
ARM = 0x01c0,
ARMv7 = 0x01c4,
ARM64 = 0xaa64,
}
[Flags]
internal enum ModuleAttributes {
ILOnly = 1,
Required32Bit = 2,
ILLibrary = 4,
StrongNameSigned = 8,
Preferred32Bit = 0x00020000,
}
[Flags]
internal enum ModuleCharacteristics {
HighEntropyVA = 0x0020,
DynamicBase = 0x0040,
NoSEH = 0x0400,
NXCompat = 0x0100,
AppContainer = 0x1000,
TerminalServerAware = 0x8000,
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil {
internal class ModuleReference : IMetadataScope {
string name;
internal MetadataToken token;
public string Name {
get { return name; }
set { name = value; }
}
public virtual MetadataScopeType MetadataScopeType {
get { return MetadataScopeType.ModuleReference; }
}
public MetadataToken MetadataToken {
get { return token; }
set { token = value; }
}
internal ModuleReference ()
{
this.token = new MetadataToken (TokenType.ModuleRef);
}
public ModuleReference (string name)
: this ()
{
this.name = name;
}
public override string ToString ()
{
return name;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil {
internal enum NativeType {
None = 0x66,
Boolean = 0x02,
I1 = 0x03,
U1 = 0x04,
I2 = 0x05,
U2 = 0x06,
I4 = 0x07,
U4 = 0x08,
I8 = 0x09,
U8 = 0x0a,
R4 = 0x0b,
R8 = 0x0c,
LPStr = 0x14,
Int = 0x1f,
UInt = 0x20,
Func = 0x26,
Array = 0x2a,
// Msft specific
Currency = 0x0f,
BStr = 0x13,
LPWStr = 0x15,
LPTStr = 0x16,
FixedSysString = 0x17,
IUnknown = 0x19,
IDispatch = 0x1a,
Struct = 0x1b,
IntF = 0x1c,
SafeArray = 0x1d,
FixedArray = 0x1e,
ByValStr = 0x22,
ANSIBStr = 0x23,
TBStr = 0x24,
VariantBool = 0x25,
ASAny = 0x28,
LPStruct = 0x2b,
CustomMarshaler = 0x2c,
Error = 0x2d,
Max = 0x50
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
[Flags]
internal enum ParameterAttributes : ushort {
None = 0x0000,
In = 0x0001, // Param is [In]
Out = 0x0002, // Param is [Out]
Lcid = 0x0004,
Retval = 0x0008,
Optional = 0x0010, // Param is optional
HasDefault = 0x1000, // Param has default value
HasFieldMarshal = 0x2000, // Param has field marshal
Unused = 0xcfe0 // Reserved: shall be zero in a conforming implementation
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal sealed class ParameterDefinition : ParameterReference, ICustomAttributeProvider, IConstantProvider, IMarshalInfoProvider {
ushort attributes;
internal IMethodSignature method;
object constant = Mixin.NotResolved;
Collection<CustomAttribute> custom_attributes;
MarshalInfo marshal_info;
public ParameterAttributes Attributes {
get { return (ParameterAttributes) attributes; }
set { attributes = (ushort) value; }
}
public IMethodSignature Method {
get { return method; }
}
public int Sequence {
get {
if (method == null)
return -1;
return method.HasImplicitThis () ? index + 1 : index;
}
}
public bool HasConstant {
get {
this.ResolveConstant (ref constant, parameter_type.Module);
return constant != Mixin.NoValue;
}
set { if (!value) constant = Mixin.NoValue; }
}
public object Constant {
get { return HasConstant ? constant : null; }
set { constant = value; }
}
public bool HasCustomAttributes {
get {
if (custom_attributes != null)
return custom_attributes.Count > 0;
return this.GetHasCustomAttributes (parameter_type.Module);
}
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, parameter_type.Module)); }
}
public bool HasMarshalInfo {
get {
if (marshal_info != null)
return true;
return this.GetHasMarshalInfo (parameter_type.Module);
}
}
public MarshalInfo MarshalInfo {
get { return marshal_info ?? (this.GetMarshalInfo (ref marshal_info, parameter_type.Module)); }
set { marshal_info = value; }
}
#region ParameterAttributes
public bool IsIn {
get { return attributes.GetAttributes ((ushort) ParameterAttributes.In); }
set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.In, value); }
}
public bool IsOut {
get { return attributes.GetAttributes ((ushort) ParameterAttributes.Out); }
set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.Out, value); }
}
public bool IsLcid {
get { return attributes.GetAttributes ((ushort) ParameterAttributes.Lcid); }
set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.Lcid, value); }
}
public bool IsReturnValue {
get { return attributes.GetAttributes ((ushort) ParameterAttributes.Retval); }
set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.Retval, value); }
}
public bool IsOptional {
get { return attributes.GetAttributes ((ushort) ParameterAttributes.Optional); }
set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.Optional, value); }
}
public bool HasDefault {
get { return attributes.GetAttributes ((ushort) ParameterAttributes.HasDefault); }
set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.HasDefault, value); }
}
public bool HasFieldMarshal {
get { return attributes.GetAttributes ((ushort) ParameterAttributes.HasFieldMarshal); }
set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.HasFieldMarshal, value); }
}
#endregion
internal ParameterDefinition (TypeReference parameterType, IMethodSignature method)
: this (string.Empty, ParameterAttributes.None, parameterType)
{
this.method = method;
}
public ParameterDefinition (TypeReference parameterType)
: this (string.Empty, ParameterAttributes.None, parameterType)
{
}
public ParameterDefinition (string name, ParameterAttributes attributes, TypeReference parameterType)
: base (name, parameterType)
{
this.attributes = (ushort) attributes;
this.token = new MetadataToken (TokenType.Param);
}
public override ParameterDefinition Resolve ()
{
return this;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Collections.Generic;
namespace Mono.Cecil {
sealed class ParameterDefinitionCollection : Collection<ParameterDefinition> {
readonly IMethodSignature method;
internal ParameterDefinitionCollection (IMethodSignature method)
{
this.method = method;
}
internal ParameterDefinitionCollection (IMethodSignature method, int capacity)
: base (capacity)
{
this.method = method;
}
protected override void OnAdd (ParameterDefinition item, int index)
{
item.method = method;
item.index = index;
}
protected override void OnInsert (ParameterDefinition item, int index)
{
item.method = method;
item.index = index;
for (int i = index; i < size; i++)
items [i].index = i + 1;
}
protected override void OnSet (ParameterDefinition item, int index)
{
item.method = method;
item.index = index;
}
protected override void OnRemove (ParameterDefinition item, int index)
{
item.method = null;
item.index = -1;
for (int i = index + 1; i < size; i++)
items [i].index = i - 1;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
internal abstract class ParameterReference : IMetadataTokenProvider {
string name;
internal int index = -1;
protected TypeReference parameter_type;
internal MetadataToken token;
public string Name {
get { return name; }
set { name = value; }
}
public int Index {
get { return index; }
}
public TypeReference ParameterType {
get { return parameter_type; }
set { parameter_type = value; }
}
public MetadataToken MetadataToken {
get { return token; }
set { token = value; }
}
internal ParameterReference (string name, TypeReference parameterType)
{
if (parameterType == null)
throw new ArgumentNullException ("parameterType");
this.name = name ?? string.Empty;
this.parameter_type = parameterType;
}
public override string ToString ()
{
return name;
}
public abstract ParameterDefinition Resolve ();
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using MD = Mono.Cecil.Metadata;
namespace Mono.Cecil {
internal sealed class PinnedType : TypeSpecification {
public override bool IsValueType {
get { return false; }
set { throw new InvalidOperationException (); }
}
public override bool IsPinned {
get { return true; }
}
public PinnedType (TypeReference type)
: base (type)
{
Mixin.CheckType (type);
this.etype = MD.ElementType.Pinned;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
[Flags]
internal enum PInvokeAttributes : ushort {
NoMangle = 0x0001, // PInvoke is to use the member name as specified
// Character set
CharSetMask = 0x0006,
CharSetNotSpec = 0x0000,
CharSetAnsi = 0x0002,
CharSetUnicode = 0x0004,
CharSetAuto = 0x0006,
SupportsLastError = 0x0040, // Information about target function. Not relevant for fields
// Calling convetion
CallConvMask = 0x0700,
CallConvWinapi = 0x0100,
CallConvCdecl = 0x0200,
CallConvStdCall = 0x0300,
CallConvThiscall = 0x0400,
CallConvFastcall = 0x0500,
BestFitMask = 0x0030,
BestFitEnabled = 0x0010,
BestFitDisabled = 0x0020,
ThrowOnUnmappableCharMask = 0x3000,
ThrowOnUnmappableCharEnabled = 0x1000,
ThrowOnUnmappableCharDisabled = 0x2000,
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil {
internal sealed class PInvokeInfo {
ushort attributes;
string entry_point;
ModuleReference module;
public PInvokeAttributes Attributes {
get { return (PInvokeAttributes) attributes; }
set { attributes = (ushort) value; }
}
public string EntryPoint {
get { return entry_point; }
set { entry_point = value; }
}
public ModuleReference Module {
get { return module; }
set { module = value; }
}
#region PInvokeAttributes
public bool IsNoMangle {
get { return attributes.GetAttributes ((ushort) PInvokeAttributes.NoMangle); }
set { attributes = attributes.SetAttributes ((ushort) PInvokeAttributes.NoMangle, value); }
}
public bool IsCharSetNotSpec {
get { return attributes.GetMaskedAttributes((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetNotSpec); }
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetNotSpec, value); }
}
public bool IsCharSetAnsi {
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAnsi); }
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAnsi, value); }
}
public bool IsCharSetUnicode {
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetUnicode); }
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetUnicode, value); }
}
public bool IsCharSetAuto {
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAuto); }
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAuto, value); }
}
public bool SupportsLastError {
get { return attributes.GetAttributes ((ushort) PInvokeAttributes.SupportsLastError); }
set { attributes = attributes.SetAttributes ((ushort) PInvokeAttributes.SupportsLastError, value); }
}
public bool IsCallConvWinapi {
get { return attributes.GetMaskedAttributes((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvWinapi); }
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvWinapi, value); }
}
public bool IsCallConvCdecl {
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvCdecl); }
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvCdecl, value); }
}
public bool IsCallConvStdCall {
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvStdCall); }
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvStdCall, value); }
}
public bool IsCallConvThiscall {
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvThiscall); }
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvThiscall, value); }
}
public bool IsCallConvFastcall {
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvFastcall); }
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvFastcall, value); }
}
public bool IsBestFitEnabled {
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitEnabled); }
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitEnabled, value); }
}
public bool IsBestFitDisabled {
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitDisabled); }
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitDisabled, value); }
}
public bool IsThrowOnUnmappableCharEnabled {
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharEnabled); }
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharEnabled, value); }
}
public bool IsThrowOnUnmappableCharDisabled {
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharDisabled); }
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharDisabled, value); }
}
#endregion
public PInvokeInfo (PInvokeAttributes attributes, string entryPoint, ModuleReference module)
{
this.attributes = (ushort) attributes;
this.entry_point = entryPoint;
this.module = module;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using MD = Mono.Cecil.Metadata;
namespace Mono.Cecil {
internal sealed class PointerType : TypeSpecification {
public override string Name {
get { return base.Name + "*"; }
}
public override string FullName {
get { return base.FullName + "*"; }
}
public override bool IsValueType {
get { return false; }
set { throw new InvalidOperationException (); }
}
public override bool IsPointer {
get { return true; }
}
public PointerType (TypeReference type)
: base (type)
{
Mixin.CheckType (type);
this.etype = MD.ElementType.Ptr;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
[Flags]
internal enum PropertyAttributes : ushort {
None = 0x0000,
SpecialName = 0x0200, // Property is special
RTSpecialName = 0x0400, // Runtime(metadata internal APIs) should check name encoding
HasDefault = 0x1000, // Property has default
Unused = 0xe9ff // Reserved: shall be zero in a conforming implementation
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System.Text;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal sealed class PropertyDefinition : PropertyReference, IMemberDefinition, IConstantProvider {
bool? has_this;
ushort attributes;
Collection<CustomAttribute> custom_attributes;
internal MethodDefinition get_method;
internal MethodDefinition set_method;
internal Collection<MethodDefinition> other_methods;
object constant = Mixin.NotResolved;
public PropertyAttributes Attributes {
get { return (PropertyAttributes) attributes; }
set { attributes = (ushort) value; }
}
public bool HasThis {
get {
if (has_this.HasValue)
return has_this.Value;
if (GetMethod != null)
return get_method.HasThis;
if (SetMethod != null)
return set_method.HasThis;
return false;
}
set { has_this = value; }
}
public bool HasCustomAttributes {
get {
if (custom_attributes != null)
return custom_attributes.Count > 0;
return this.GetHasCustomAttributes (Module);
}
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); }
}
public MethodDefinition GetMethod {
get {
if (get_method != null)
return get_method;
InitializeMethods ();
return get_method;
}
set { get_method = value; }
}
public MethodDefinition SetMethod {
get {
if (set_method != null)
return set_method;
InitializeMethods ();
return set_method;
}
set { set_method = value; }
}
public bool HasOtherMethods {
get {
if (other_methods != null)
return other_methods.Count > 0;
InitializeMethods ();
return !other_methods.IsNullOrEmpty ();
}
}
public Collection<MethodDefinition> OtherMethods {
get {
if (other_methods != null)
return other_methods;
InitializeMethods ();
if (other_methods != null)
return other_methods;
return other_methods = new Collection<MethodDefinition> ();
}
}
public bool HasParameters {
get {
InitializeMethods ();
if (get_method != null)
return get_method.HasParameters;
if (set_method != null)
return set_method.HasParameters && set_method.Parameters.Count > 1;
return false;
}
}
public override Collection<ParameterDefinition> Parameters {
get {
InitializeMethods ();
if (get_method != null)
return MirrorParameters (get_method, 0);
if (set_method != null)
return MirrorParameters (set_method, 1);
return new Collection<ParameterDefinition> ();
}
}
static Collection<ParameterDefinition> MirrorParameters (MethodDefinition method, int bound)
{
var parameters = new Collection<ParameterDefinition> ();
if (!method.HasParameters)
return parameters;
var original_parameters = method.Parameters;
var end = original_parameters.Count - bound;
for (int i = 0; i < end; i++)
parameters.Add (original_parameters [i]);
return parameters;
}
public bool HasConstant {
get {
this.ResolveConstant (ref constant, Module);
return constant != Mixin.NoValue;
}
set { if (!value) constant = Mixin.NoValue; }
}
public object Constant {
get { return HasConstant ? constant : null; }
set { constant = value; }
}
#region PropertyAttributes
public bool IsSpecialName {
get { return attributes.GetAttributes ((ushort) PropertyAttributes.SpecialName); }
set { attributes = attributes.SetAttributes ((ushort) PropertyAttributes.SpecialName, value); }
}
public bool IsRuntimeSpecialName {
get { return attributes.GetAttributes ((ushort) PropertyAttributes.RTSpecialName); }
set { attributes = attributes.SetAttributes ((ushort) PropertyAttributes.RTSpecialName, value); }
}
public bool HasDefault {
get { return attributes.GetAttributes ((ushort) PropertyAttributes.HasDefault); }
set { attributes = attributes.SetAttributes ((ushort) PropertyAttributes.HasDefault, value); }
}
#endregion
public new TypeDefinition DeclaringType {
get { return (TypeDefinition) base.DeclaringType; }
set { base.DeclaringType = value; }
}
public override bool IsDefinition {
get { return true; }
}
public override string FullName {
get {
var builder = new StringBuilder ();
builder.Append (PropertyType.ToString ());
builder.Append (' ');
builder.Append (MemberFullName ());
builder.Append ('(');
if (HasParameters) {
var parameters = Parameters;
for (int i = 0; i < parameters.Count; i++) {
if (i > 0)
builder.Append (',');
builder.Append (parameters [i].ParameterType.FullName);
}
}
builder.Append (')');
return builder.ToString ();
}
}
public PropertyDefinition (string name, PropertyAttributes attributes, TypeReference propertyType)
: base (name, propertyType)
{
this.attributes = (ushort) attributes;
this.token = new MetadataToken (TokenType.Property);
}
void InitializeMethods ()
{
var module = this.Module;
if (module == null)
return;
lock (module.SyncRoot) {
if (get_method != null || set_method != null)
return;
if (!module.HasImage ())
return;
module.Read (this, (property, reader) => reader.ReadMethods (property));
}
}
public override PropertyDefinition Resolve ()
{
return this;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal abstract class PropertyReference : MemberReference {
TypeReference property_type;
public TypeReference PropertyType {
get { return property_type; }
set { property_type = value; }
}
public abstract Collection<ParameterDefinition> Parameters {
get;
}
internal PropertyReference (string name, TypeReference propertyType)
: base (name)
{
Mixin.CheckType (propertyType, Mixin.Argument.propertyType);
property_type = propertyType;
}
protected override IMemberDefinition ResolveDefinition ()
{
return this.Resolve ();
}
public new abstract PropertyDefinition Resolve ();
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using MD = Mono.Cecil.Metadata;
namespace Mono.Cecil {
internal sealed class ByReferenceType : TypeSpecification {
public override string Name {
get { return base.Name + "&"; }
}
public override string FullName {
get { return base.FullName + "&"; }
}
public override bool IsValueType {
get { return false; }
set { throw new InvalidOperationException (); }
}
public override bool IsByReference {
get { return true; }
}
public ByReferenceType (TypeReference type)
: base (type)
{
Mixin.CheckType (type);
this.etype = MD.ElementType.ByRef;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil {
internal enum ResourceType {
Linked,
Embedded,
AssemblyLinked,
}
internal abstract class Resource {
string name;
uint attributes;
public string Name {
get { return name; }
set { name = value; }
}
public ManifestResourceAttributes Attributes {
get { return (ManifestResourceAttributes) attributes; }
set { attributes = (uint) value; }
}
public abstract ResourceType ResourceType {
get;
}
#region ManifestResourceAttributes
public bool IsPublic {
get { return attributes.GetMaskedAttributes ((uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Public); }
set { attributes = attributes.SetMaskedAttributes ((uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Public, value); }
}
public bool IsPrivate {
get { return attributes.GetMaskedAttributes ((uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Private); }
set { attributes = attributes.SetMaskedAttributes ((uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Private, value); }
}
#endregion
internal Resource (string name, ManifestResourceAttributes attributes)
{
this.name = name;
this.attributes = (uint) attributes;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Diagnostics;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal enum SecurityAction : ushort {
Request = 1,
Demand = 2,
Assert = 3,
Deny = 4,
PermitOnly = 5,
LinkDemand = 6,
InheritDemand = 7,
RequestMinimum = 8,
RequestOptional = 9,
RequestRefuse = 10,
PreJitGrant = 11,
PreJitDeny = 12,
NonCasDemand = 13,
NonCasLinkDemand = 14,
NonCasInheritance = 15
}
internal interface ISecurityDeclarationProvider : IMetadataTokenProvider {
bool HasSecurityDeclarations { get; }
Collection<SecurityDeclaration> SecurityDeclarations { get; }
}
[DebuggerDisplay ("{AttributeType}")]
internal sealed class SecurityAttribute : ICustomAttribute {
TypeReference attribute_type;
internal Collection<CustomAttributeNamedArgument> fields;
internal Collection<CustomAttributeNamedArgument> properties;
public TypeReference AttributeType {
get { return attribute_type; }
set { attribute_type = value; }
}
public bool HasFields {
get { return !fields.IsNullOrEmpty (); }
}
public Collection<CustomAttributeNamedArgument> Fields {
get { return fields ?? (fields = new Collection<CustomAttributeNamedArgument> ()); }
}
public bool HasProperties {
get { return !properties.IsNullOrEmpty (); }
}
public Collection<CustomAttributeNamedArgument> Properties {
get { return properties ?? (properties = new Collection<CustomAttributeNamedArgument> ()); }
}
public SecurityAttribute (TypeReference attributeType)
{
this.attribute_type = attributeType;
}
bool ICustomAttribute.HasConstructorArguments {
get { return false; }
}
Collection<CustomAttributeArgument> ICustomAttribute.ConstructorArguments {
get { throw new NotSupportedException (); }
}
}
internal sealed class SecurityDeclaration {
readonly internal uint signature;
byte [] blob;
readonly ModuleDefinition module;
internal bool resolved;
SecurityAction action;
internal Collection<SecurityAttribute> security_attributes;
public SecurityAction Action {
get { return action; }
set { action = value; }
}
public bool HasSecurityAttributes {
get {
Resolve ();
return !security_attributes.IsNullOrEmpty ();
}
}
public Collection<SecurityAttribute> SecurityAttributes {
get {
Resolve ();
return security_attributes ?? (security_attributes = new Collection<SecurityAttribute> ());
}
}
internal bool HasImage {
get { return module != null && module.HasImage; }
}
internal SecurityDeclaration (SecurityAction action, uint signature, ModuleDefinition module)
{
this.action = action;
this.signature = signature;
this.module = module;
}
public SecurityDeclaration (SecurityAction action)
{
this.action = action;
this.resolved = true;
}
public SecurityDeclaration (SecurityAction action, byte [] blob)
{
this.action = action;
this.resolved = false;
this.blob = blob;
}
public byte [] GetBlob ()
{
if (blob != null)
return blob;
if (!HasImage || signature == 0)
throw new NotSupportedException ();
return blob = module.Read (this, (declaration, reader) => reader.ReadSecurityDeclarationBlob (declaration.signature));
}
void Resolve ()
{
if (resolved || !HasImage)
return;
module.Read (this, (declaration, reader) => reader.ReadSecurityDeclarationSignature (declaration));
resolved = true;
}
}
static partial class Mixin {
public static bool GetHasSecurityDeclarations (
this ISecurityDeclarationProvider self,
ModuleDefinition module)
{
return module.HasImage () && module.Read (self, (provider, reader) => reader.HasSecurityDeclarations (provider));
}
public static Collection<SecurityDeclaration> GetSecurityDeclarations (
this ISecurityDeclarationProvider self,
ref Collection<SecurityDeclaration> variable,
ModuleDefinition module)
{
return module.HasImage ()
? module.Read (ref variable, self, (provider, reader) => reader.ReadSecurityDeclarations (provider))
: variable = new Collection<SecurityDeclaration>();
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using MD = Mono.Cecil.Metadata;
namespace Mono.Cecil {
internal sealed class SentinelType : TypeSpecification {
public override bool IsValueType {
get { return false; }
set { throw new InvalidOperationException (); }
}
public override bool IsSentinel {
get { return true; }
}
public SentinelType (TypeReference type)
: base (type)
{
Mixin.CheckType (type);
this.etype = MD.ElementType.Sentinel;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil {
internal enum TargetRuntime {
Net_1_0,
Net_1_1,
Net_2_0,
Net_4_0,
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
[Flags]
enum TypeDefinitionTreatment {
None = 0x0,
KindMask = 0xf,
NormalType = 0x1,
NormalAttribute = 0x2,
UnmangleWindowsRuntimeName = 0x3,
PrefixWindowsRuntimeName = 0x4,
RedirectToClrType = 0x5,
RedirectToClrAttribute = 0x6,
Abstract = 0x10,
Internal = 0x20,
}
enum TypeReferenceTreatment {
None = 0x0,
SystemDelegate = 0x1,
SystemAttribute = 0x2,
UseProjectionInfo = 0x3,
}
[Flags]
enum MethodDefinitionTreatment {
None = 0x0,
Dispose = 0x1,
Abstract = 0x2,
Private = 0x4,
Public = 0x8,
Runtime = 0x10,
InternalCall = 0x20,
}
enum FieldDefinitionTreatment {
None = 0x0,
Public = 0x1,
}
enum MemberReferenceTreatment {
None = 0x0,
Dispose = 0x1,
}
enum CustomAttributeValueTreatment {
None = 0x0,
AllowSingle = 0x1,
AllowMultiple = 0x2,
VersionAttribute = 0x3,
DeprecatedAttribute = 0x4,
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
[Flags]
internal enum TypeAttributes : uint {
// Visibility attributes
VisibilityMask = 0x00000007, // Use this mask to retrieve visibility information
NotPublic = 0x00000000, // Class has no public scope
Public = 0x00000001, // Class has public scope
NestedPublic = 0x00000002, // Class is nested with public visibility
NestedPrivate = 0x00000003, // Class is nested with private visibility
NestedFamily = 0x00000004, // Class is nested with family visibility
NestedAssembly = 0x00000005, // Class is nested with assembly visibility
NestedFamANDAssem = 0x00000006, // Class is nested with family and assembly visibility
NestedFamORAssem = 0x00000007, // Class is nested with family or assembly visibility
// Class layout attributes
LayoutMask = 0x00000018, // Use this mask to retrieve class layout information
AutoLayout = 0x00000000, // Class fields are auto-laid out
SequentialLayout = 0x00000008, // Class fields are laid out sequentially
ExplicitLayout = 0x00000010, // Layout is supplied explicitly
// Class semantics attributes
ClassSemanticMask = 0x00000020, // Use this mask to retrieve class semantics information
Class = 0x00000000, // Type is a class
Interface = 0x00000020, // Type is an interface
// Special semantics in addition to class semantics
Abstract = 0x00000080, // Class is abstract
Sealed = 0x00000100, // Class cannot be extended
SpecialName = 0x00000400, // Class name is special
// Implementation attributes
Import = 0x00001000, // Class/Interface is imported
Serializable = 0x00002000, // Class is serializable
WindowsRuntime = 0x00004000, // Windows Runtime type
// String formatting attributes
StringFormatMask = 0x00030000, // Use this mask to retrieve string information for native interop
AnsiClass = 0x00000000, // LPSTR is interpreted as ANSI
UnicodeClass = 0x00010000, // LPSTR is interpreted as Unicode
AutoClass = 0x00020000, // LPSTR is interpreted automatically
// Class initialization attributes
BeforeFieldInit = 0x00100000, // Initialize the class before first static field access
// Additional flags
RTSpecialName = 0x00000800, // CLI provides 'special' behavior, depending upon the name of the Type
HasSecurity = 0x00040000, // Type has security associate with it
Forwarder = 0x00200000, // Exported type is a type forwarder
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Cecil.Metadata;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal sealed class TypeDefinition : TypeReference, IMemberDefinition, ISecurityDeclarationProvider {
uint attributes;
TypeReference base_type;
internal Range fields_range;
internal Range methods_range;
short packing_size = Mixin.NotResolvedMarker;
int class_size = Mixin.NotResolvedMarker;
InterfaceImplementationCollection interfaces;
Collection<TypeDefinition> nested_types;
Collection<MethodDefinition> methods;
Collection<FieldDefinition> fields;
Collection<EventDefinition> events;
Collection<PropertyDefinition> properties;
Collection<CustomAttribute> custom_attributes;
Collection<SecurityDeclaration> security_declarations;
public TypeAttributes Attributes {
get { return (TypeAttributes) attributes; }
set {
if (IsWindowsRuntimeProjection && (ushort) value != attributes)
throw new InvalidOperationException ();
attributes = (uint) value;
}
}
public TypeReference BaseType {
get { return base_type; }
set { base_type = value; }
}
public override string Name {
get { return base.Name; }
set {
if (IsWindowsRuntimeProjection && value != base.Name)
throw new InvalidOperationException ();
base.Name = value;
}
}
void ResolveLayout ()
{
if (packing_size != Mixin.NotResolvedMarker || class_size != Mixin.NotResolvedMarker)
return;
if (!HasImage) {
packing_size = Mixin.NoDataMarker;
class_size = Mixin.NoDataMarker;
return;
}
var row = Module.Read (this, (type, reader) => reader.ReadTypeLayout (type));
packing_size = row.Col1;
class_size = row.Col2;
}
public bool HasLayoutInfo {
get {
if (packing_size >= 0 || class_size >= 0)
return true;
ResolveLayout ();
return packing_size >= 0 || class_size >= 0;
}
}
public short PackingSize {
get {
if (packing_size >= 0)
return packing_size;
ResolveLayout ();
return packing_size >= 0 ? packing_size : (short) -1;
}
set { packing_size = value; }
}
public int ClassSize {
get {
if (class_size >= 0)
return class_size;
ResolveLayout ();
return class_size >= 0 ? class_size : -1;
}
set { class_size = value; }
}
public bool HasInterfaces {
get {
if (interfaces != null)
return interfaces.Count > 0;
return HasImage && Module.Read (this, (type, reader) => reader.HasInterfaces (type));
}
}
public Collection<InterfaceImplementation> Interfaces {
get {
if (interfaces != null)
return interfaces;
if (HasImage)
return Module.Read (ref interfaces, this, (type, reader) => reader.ReadInterfaces (type));
return interfaces = new InterfaceImplementationCollection (this);
}
}
public bool HasNestedTypes {
get {
if (nested_types != null)
return nested_types.Count > 0;
return HasImage && Module.Read (this, (type, reader) => reader.HasNestedTypes (type));
}
}
public Collection<TypeDefinition> NestedTypes {
get {
if (nested_types != null)
return nested_types;
if (HasImage)
return Module.Read (ref nested_types, this, (type, reader) => reader.ReadNestedTypes (type));
return nested_types = new MemberDefinitionCollection<TypeDefinition> (this);
}
}
public bool HasMethods {
get {
if (methods != null)
return methods.Count > 0;
return HasImage && methods_range.Length > 0;
}
}
public Collection<MethodDefinition> Methods {
get {
if (methods != null)
return methods;
if (HasImage)
return Module.Read (ref methods, this, (type, reader) => reader.ReadMethods (type));
return methods = new MemberDefinitionCollection<MethodDefinition> (this);
}
}
public bool HasFields {
get {
if (fields != null)
return fields.Count > 0;
return HasImage && fields_range.Length > 0;
}
}
public Collection<FieldDefinition> Fields {
get {
if (fields != null)
return fields;
if (HasImage)
return Module.Read (ref fields, this, (type, reader) => reader.ReadFields (type));
return fields = new MemberDefinitionCollection<FieldDefinition> (this);
}
}
public bool HasEvents {
get {
if (events != null)
return events.Count > 0;
return HasImage && Module.Read (this, (type, reader) => reader.HasEvents (type));
}
}
public Collection<EventDefinition> Events {
get {
if (events != null)
return events;
if (HasImage)
return Module.Read (ref events, this, (type, reader) => reader.ReadEvents (type));
return events = new MemberDefinitionCollection<EventDefinition> (this);
}
}
public bool HasProperties {
get {
if (properties != null)
return properties.Count > 0;
return HasImage && Module.Read (this, (type, reader) => reader.HasProperties (type));
}
}
public Collection<PropertyDefinition> Properties {
get {
if (properties != null)
return properties;
if (HasImage)
return Module.Read (ref properties, this, (type, reader) => reader.ReadProperties (type));
return properties = new MemberDefinitionCollection<PropertyDefinition> (this);
}
}
public bool HasSecurityDeclarations {
get {
if (security_declarations != null)
return security_declarations.Count > 0;
return this.GetHasSecurityDeclarations (Module);
}
}
public Collection<SecurityDeclaration> SecurityDeclarations {
get { return security_declarations ?? (this.GetSecurityDeclarations (ref security_declarations, Module)); }
}
public bool HasCustomAttributes {
get {
if (custom_attributes != null)
return custom_attributes.Count > 0;
return this.GetHasCustomAttributes (Module);
}
}
public Collection<CustomAttribute> CustomAttributes {
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); }
}
public override bool HasGenericParameters {
get {
if (generic_parameters != null)
return generic_parameters.Count > 0;
return this.GetHasGenericParameters (Module);
}
}
public override Collection<GenericParameter> GenericParameters {
get { return generic_parameters ?? (this.GetGenericParameters (ref generic_parameters, Module)); }
}
#region TypeAttributes
public bool IsNotPublic {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic, value); }
}
public bool IsPublic {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public, value); }
}
public bool IsNestedPublic {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic, value); }
}
public bool IsNestedPrivate {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate, value); }
}
public bool IsNestedFamily {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily, value); }
}
public bool IsNestedAssembly {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly, value); }
}
public bool IsNestedFamilyAndAssembly {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem, value); }
}
public bool IsNestedFamilyOrAssembly {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem, value); }
}
public bool IsAutoLayout {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout, value); }
}
public bool IsSequentialLayout {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout, value); }
}
public bool IsExplicitLayout {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout, value); }
}
public bool IsClass {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class, value); }
}
public bool IsInterface {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface, value); }
}
public bool IsAbstract {
get { return attributes.GetAttributes ((uint) TypeAttributes.Abstract); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Abstract, value); }
}
public bool IsSealed {
get { return attributes.GetAttributes ((uint) TypeAttributes.Sealed); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Sealed, value); }
}
public bool IsSpecialName {
get { return attributes.GetAttributes ((uint) TypeAttributes.SpecialName); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.SpecialName, value); }
}
public bool IsImport {
get { return attributes.GetAttributes ((uint) TypeAttributes.Import); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Import, value); }
}
public bool IsSerializable {
get { return attributes.GetAttributes ((uint) TypeAttributes.Serializable); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Serializable, value); }
}
public bool IsWindowsRuntime {
get { return attributes.GetAttributes ((uint) TypeAttributes.WindowsRuntime); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.WindowsRuntime, value); }
}
public bool IsAnsiClass {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass, value); }
}
public bool IsUnicodeClass {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass, value); }
}
public bool IsAutoClass {
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass); }
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass, value); }
}
public bool IsBeforeFieldInit {
get { return attributes.GetAttributes ((uint) TypeAttributes.BeforeFieldInit); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.BeforeFieldInit, value); }
}
public bool IsRuntimeSpecialName {
get { return attributes.GetAttributes ((uint) TypeAttributes.RTSpecialName); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.RTSpecialName, value); }
}
public bool HasSecurity {
get { return attributes.GetAttributes ((uint) TypeAttributes.HasSecurity); }
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.HasSecurity, value); }
}
#endregion
public bool IsEnum {
get { return base_type != null && base_type.IsTypeOf ("System", "Enum"); }
}
public override bool IsValueType {
get {
if (base_type == null)
return false;
return base_type.IsTypeOf ("System", "Enum") || (base_type.IsTypeOf ("System", "ValueType") && !this.IsTypeOf ("System", "Enum"));
}
set {
throw new NotSupportedException ();
}
}
public override bool IsPrimitive {
get {
ElementType primitive_etype;
return MetadataSystem.TryGetPrimitiveElementType (this, out primitive_etype) && primitive_etype.IsPrimitive ();
}
}
public override MetadataType MetadataType {
get {
ElementType primitive_etype;
if (MetadataSystem.TryGetPrimitiveElementType (this, out primitive_etype))
return (MetadataType) primitive_etype;
return base.MetadataType;
}
}
public override bool IsDefinition {
get { return true; }
}
public new TypeDefinition DeclaringType {
get { return (TypeDefinition) base.DeclaringType; }
set { base.DeclaringType = value; }
}
internal new TypeDefinitionProjection WindowsRuntimeProjection {
get { return (TypeDefinitionProjection) projection; }
set { projection = value; }
}
public TypeDefinition (string @namespace, string name, TypeAttributes attributes)
: base (@namespace, name)
{
this.attributes = (uint) attributes;
this.token = new MetadataToken (TokenType.TypeDef);
}
public TypeDefinition (string @namespace, string name, TypeAttributes attributes, TypeReference baseType) :
this (@namespace, name, attributes)
{
this.BaseType = baseType;
}
protected override void ClearFullName ()
{
base.ClearFullName ();
if (!HasNestedTypes)
return;
var nested_types = this.NestedTypes;
for (int i = 0; i < nested_types.Count; i++)
nested_types [i].ClearFullName ();
}
public override TypeDefinition Resolve ()
{
return this;
}
}
internal sealed class InterfaceImplementation : ICustomAttributeProvider
{
internal TypeDefinition type;
internal MetadataToken token;
TypeReference interface_type;
Collection<CustomAttribute> custom_attributes;
public TypeReference InterfaceType {
get { return interface_type; }
set { interface_type = value; }
}
public bool HasCustomAttributes {
get {
if (custom_attributes != null)
return custom_attributes.Count > 0;
if (type == null)
return false;
return this.GetHasCustomAttributes (type.Module);
}
}
public Collection<CustomAttribute> CustomAttributes {
get {
if (type == null)
return custom_attributes = new Collection<CustomAttribute> ();
return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, type.Module));
}
}
public MetadataToken MetadataToken {
get { return token; }
set { token = value; }
}
internal InterfaceImplementation (TypeReference interfaceType, MetadataToken token)
{
this.interface_type = interfaceType;
this.token = token;
}
public InterfaceImplementation (TypeReference interfaceType)
{
Mixin.CheckType (interfaceType, Mixin.Argument.interfaceType);
this.interface_type = interfaceType;
this.token = new MetadataToken (TokenType.InterfaceImpl);
}
}
class InterfaceImplementationCollection : Collection<InterfaceImplementation>
{
readonly TypeDefinition type;
internal InterfaceImplementationCollection (TypeDefinition type)
{
this.type = type;
}
internal InterfaceImplementationCollection (TypeDefinition type, int length)
: base (length)
{
this.type = type;
}
protected override void OnAdd (InterfaceImplementation item, int index)
{
item.type = type;
}
protected override void OnInsert (InterfaceImplementation item, int index)
{
item.type = type;
}
protected override void OnSet (InterfaceImplementation item, int index)
{
item.type = type;
}
protected override void OnRemove (InterfaceImplementation item, int index)
{
item.type = null;
}
}
static partial class Mixin {
public static TypeReference GetEnumUnderlyingType (this TypeDefinition self)
{
var fields = self.Fields;
for (int i = 0; i < fields.Count; i++) {
var field = fields [i];
if (!field.IsStatic)
return field.FieldType;
}
throw new ArgumentException ();
}
public static TypeDefinition GetNestedType (this TypeDefinition self, string fullname)
{
if (!self.HasNestedTypes)
return null;
var nested_types = self.NestedTypes;
for (int i = 0; i < nested_types.Count; i++) {
var nested_type = nested_types [i];
if (nested_type.TypeFullName () == fullname)
return nested_type;
}
return null;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Collections.Generic;
using Mono.Cecil.Metadata;
using Mono.Collections.Generic;
namespace Mono.Cecil {
using Slot = Row<string, string>;
sealed class TypeDefinitionCollection : Collection<TypeDefinition> {
readonly ModuleDefinition container;
readonly Dictionary<Slot, TypeDefinition> name_cache;
internal TypeDefinitionCollection (ModuleDefinition container)
{
this.container = container;
this.name_cache = new Dictionary<Slot, TypeDefinition> (new RowEqualityComparer ());
}
internal TypeDefinitionCollection (ModuleDefinition container, int capacity)
: base (capacity)
{
this.container = container;
this.name_cache = new Dictionary<Slot, TypeDefinition> (capacity, new RowEqualityComparer ());
}
protected override void OnAdd (TypeDefinition item, int index)
{
Attach (item);
}
protected override void OnSet (TypeDefinition item, int index)
{
Attach (item);
}
protected override void OnInsert (TypeDefinition item, int index)
{
Attach (item);
}
protected override void OnRemove (TypeDefinition item, int index)
{
Detach (item);
}
protected override void OnClear ()
{
foreach (var type in this)
Detach (type);
}
void Attach (TypeDefinition type)
{
if (type.Module != null && type.Module != container)
throw new ArgumentException ("Type already attached");
type.module = container;
type.scope = container;
name_cache [new Slot (type.Namespace, type.Name)] = type;
}
void Detach (TypeDefinition type)
{
type.module = null;
type.scope = null;
name_cache.Remove (new Slot (type.Namespace, type.Name));
}
public TypeDefinition GetType (string fullname)
{
string @namespace, name;
TypeParser.SplitFullName (fullname, out @namespace, out name);
return GetType (@namespace, name);
}
public TypeDefinition GetType (string @namespace, string name)
{
TypeDefinition type;
if (name_cache.TryGetValue (new Slot (@namespace, name), out type))
return type;
return null;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Text;
using Mono.Cecil.Metadata;
namespace Mono.Cecil {
class TypeParser {
class Type {
public const int Ptr = -1;
public const int ByRef = -2;
public const int SzArray = -3;
public string type_fullname;
public string [] nested_names;
public int arity;
public int [] specs;
public Type [] generic_arguments;
public string assembly;
}
readonly string fullname;
readonly int length;
int position;
TypeParser (string fullname)
{
this.fullname = fullname;
this.length = fullname.Length;
}
Type ParseType (bool fq_name)
{
var type = new Type ();
type.type_fullname = ParsePart ();
type.nested_names = ParseNestedNames ();
if (TryGetArity (type))
type.generic_arguments = ParseGenericArguments (type.arity);
type.specs = ParseSpecs ();
if (fq_name)
type.assembly = ParseAssemblyName ();
return type;
}
static bool TryGetArity (Type type)
{
int arity = 0;
TryAddArity (type.type_fullname, ref arity);
var nested_names = type.nested_names;
if (!nested_names.IsNullOrEmpty ()) {
for (int i = 0; i < nested_names.Length; i++)
TryAddArity (nested_names [i], ref arity);
}
type.arity = arity;
return arity > 0;
}
static bool TryGetArity (string name, out int arity)
{
arity = 0;
var index = name.LastIndexOf ('`');
if (index == -1)
return false;
return ParseInt32 (name.Substring (index + 1), out arity);
}
static bool ParseInt32 (string value, out int result)
{
return int.TryParse (value, out result);
}
static void TryAddArity (string name, ref int arity)
{
int type_arity;
if (!TryGetArity (name, out type_arity))
return;
arity += type_arity;
}
string ParsePart ()
{
var part = new StringBuilder ();
while (position < length && !IsDelimiter (fullname [position])) {
if (fullname [position] == '\\')
position++;
part.Append (fullname [position++]);
}
return part.ToString ();
}
static bool IsDelimiter (char chr)
{
return "+,[]*&".IndexOf (chr) != -1;
}
void TryParseWhiteSpace ()
{
while (position < length && Char.IsWhiteSpace (fullname [position]))
position++;
}
string [] ParseNestedNames ()
{
string [] nested_names = null;
while (TryParse ('+'))
Add (ref nested_names, ParsePart ());
return nested_names;
}
bool TryParse (char chr)
{
if (position < length && fullname [position] == chr) {
position++;
return true;
}
return false;
}
static void Add<T> (ref T [] array, T item)
{
array = array.Add (item);
}
int [] ParseSpecs ()
{
int [] specs = null;
while (position < length) {
switch (fullname [position]) {
case '*':
position++;
Add (ref specs, Type.Ptr);
break;
case '&':
position++;
Add (ref specs, Type.ByRef);
break;
case '[':
position++;
switch (fullname [position]) {
case ']':
position++;
Add (ref specs, Type.SzArray);
break;
case '*':
position++;
Add (ref specs, 1);
break;
default:
var rank = 1;
while (TryParse (','))
rank++;
Add (ref specs, rank);
TryParse (']');
break;
}
break;
default:
return specs;
}
}
return specs;
}
Type [] ParseGenericArguments (int arity)
{
Type [] generic_arguments = null;
if (position == length || fullname [position] != '[')
return generic_arguments;
TryParse ('[');
for (int i = 0; i < arity; i++) {
var fq_argument = TryParse ('[');
Add (ref generic_arguments, ParseType (fq_argument));
if (fq_argument)
TryParse (']');
TryParse (',');
TryParseWhiteSpace ();
}
TryParse (']');
return generic_arguments;
}
string ParseAssemblyName ()
{
if (!TryParse (','))
return string.Empty;
TryParseWhiteSpace ();
var start = position;
while (position < length) {
var chr = fullname [position];
if (chr == '[' || chr == ']')
break;
position++;
}
return fullname.Substring (start, position - start);
}
public static TypeReference ParseType (ModuleDefinition module, string fullname, bool typeDefinitionOnly = false)
{
if (string.IsNullOrEmpty (fullname))
return null;
var parser = new TypeParser (fullname);
return GetTypeReference (module, parser.ParseType (true), typeDefinitionOnly);
}
static TypeReference GetTypeReference (ModuleDefinition module, Type type_info, bool type_def_only)
{
TypeReference type;
if (!TryGetDefinition (module, type_info, out type)) {
if (type_def_only)
return null;
type = CreateReference (type_info, module, GetMetadataScope (module, type_info));
}
return CreateSpecs (type, type_info);
}
static TypeReference CreateSpecs (TypeReference type, Type type_info)
{
type = TryCreateGenericInstanceType (type, type_info);
var specs = type_info.specs;
if (specs.IsNullOrEmpty ())
return type;
for (int i = 0; i < specs.Length; i++) {
switch (specs [i]) {
case Type.Ptr:
type = new PointerType (type);
break;
case Type.ByRef:
type = new ByReferenceType (type);
break;
case Type.SzArray:
type = new ArrayType (type);
break;
default:
var array = new ArrayType (type);
array.Dimensions.Clear ();
for (int j = 0; j < specs [i]; j++)
array.Dimensions.Add (new ArrayDimension ());
type = array;
break;
}
}
return type;
}
static TypeReference TryCreateGenericInstanceType (TypeReference type, Type type_info)
{
var generic_arguments = type_info.generic_arguments;
if (generic_arguments.IsNullOrEmpty ())
return type;
var instance = new GenericInstanceType (type);
var instance_arguments = instance.GenericArguments;
for (int i = 0; i < generic_arguments.Length; i++)
instance_arguments.Add (GetTypeReference (type.Module, generic_arguments [i], false));
return instance;
}
public static void SplitFullName (string fullname, out string @namespace, out string name)
{
var last_dot = fullname.LastIndexOf ('.');
if (last_dot == -1) {
@namespace = string.Empty;
name = fullname;
} else {
@namespace = fullname.Substring (0, last_dot);
name = fullname.Substring (last_dot + 1);
}
}
static TypeReference CreateReference (Type type_info, ModuleDefinition module, IMetadataScope scope)
{
string @namespace, name;
SplitFullName (type_info.type_fullname, out @namespace, out name);
var type = new TypeReference (@namespace, name, module, scope);
MetadataSystem.TryProcessPrimitiveTypeReference (type);
AdjustGenericParameters (type);
var nested_names = type_info.nested_names;
if (nested_names.IsNullOrEmpty ())
return type;
for (int i = 0; i < nested_names.Length; i++) {
type = new TypeReference (string.Empty, nested_names [i], module, null) {
DeclaringType = type,
};
AdjustGenericParameters (type);
}
return type;
}
static void AdjustGenericParameters (TypeReference type)
{
int arity;
if (!TryGetArity (type.Name, out arity))
return;
for (int i = 0; i < arity; i++)
type.GenericParameters.Add (new GenericParameter (type));
}
static IMetadataScope GetMetadataScope (ModuleDefinition module, Type type_info)
{
if (string.IsNullOrEmpty (type_info.assembly))
return module.TypeSystem.CoreLibrary;
AssemblyNameReference match;
var reference = AssemblyNameReference.Parse (type_info.assembly);
return module.TryGetAssemblyNameReference (reference, out match)
? match
: reference;
}
static bool TryGetDefinition (ModuleDefinition module, Type type_info, out TypeReference type)
{
type = null;
if (!TryCurrentModule (module, type_info))
return false;
var typedef = module.GetType (type_info.type_fullname);
if (typedef == null)
return false;
var nested_names = type_info.nested_names;
if (!nested_names.IsNullOrEmpty ()) {
for (int i = 0; i < nested_names.Length; i++) {
var nested_type = typedef.GetNestedType (nested_names [i]);
if (nested_type == null)
return false;
typedef = nested_type;
}
}
type = typedef;
return true;
}
static bool TryCurrentModule (ModuleDefinition module, Type type_info)
{
if (string.IsNullOrEmpty (type_info.assembly))
return true;
if (module.assembly != null && module.assembly.Name.FullName == type_info.assembly)
return true;
return false;
}
public static string ToParseable (TypeReference type, bool top_level = true)
{
if (type == null)
return null;
var name = new StringBuilder ();
AppendType (type, name, true, top_level);
return name.ToString ();
}
static void AppendNamePart (string part, StringBuilder name)
{
foreach (var c in part) {
if (IsDelimiter (c))
name.Append ('\\');
name.Append (c);
}
}
static void AppendType (TypeReference type, StringBuilder name, bool fq_name, bool top_level)
{
var element_type = type.GetElementType ();
var declaring_type = element_type.DeclaringType;
if (declaring_type != null) {
AppendType (declaring_type, name, false, top_level);
name.Append ('+');
}
var @namespace = type.Namespace;
if (!string.IsNullOrEmpty (@namespace)) {
AppendNamePart (@namespace, name);
name.Append ('.');
}
AppendNamePart (element_type.Name, name);
if (!fq_name)
return;
if (type.IsTypeSpecification ())
AppendTypeSpecification ((TypeSpecification) type, name);
if (RequiresFullyQualifiedName (type, top_level)) {
name.Append (", ");
name.Append (GetScopeFullName (type));
}
}
static string GetScopeFullName (TypeReference type)
{
var scope = type.Scope;
switch (scope.MetadataScopeType) {
case MetadataScopeType.AssemblyNameReference:
return ((AssemblyNameReference) scope).FullName;
case MetadataScopeType.ModuleDefinition:
return ((ModuleDefinition) scope).Assembly.Name.FullName;
}
throw new ArgumentException ();
}
static void AppendTypeSpecification (TypeSpecification type, StringBuilder name)
{
if (type.ElementType.IsTypeSpecification ())
AppendTypeSpecification ((TypeSpecification) type.ElementType, name);
switch (type.etype) {
case ElementType.Ptr:
name.Append ('*');
break;
case ElementType.ByRef:
name.Append ('&');
break;
case ElementType.SzArray:
case ElementType.Array:
var array = (ArrayType) type;
if (array.IsVector) {
name.Append ("[]");
} else {
name.Append ('[');
for (int i = 1; i < array.Rank; i++)
name.Append (',');
name.Append (']');
}
break;
case ElementType.GenericInst:
var instance = (GenericInstanceType) type;
var arguments = instance.GenericArguments;
name.Append ('[');
for (int i = 0; i < arguments.Count; i++) {
if (i > 0)
name.Append (',');
var argument = arguments [i];
var requires_fqname = argument.Scope != argument.Module;
if (requires_fqname)
name.Append ('[');
AppendType (argument, name, true, false);
if (requires_fqname)
name.Append (']');
}
name.Append (']');
break;
default:
return;
}
}
static bool RequiresFullyQualifiedName (TypeReference type, bool top_level)
{
if (type.Scope == type.Module)
return false;
if (type.Scope.Name == "mscorlib" && top_level)
return false;
return true;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Cecil.Metadata;
using Mono.Collections.Generic;
namespace Mono.Cecil {
internal enum MetadataType : byte {
Void = ElementType.Void,
Boolean = ElementType.Boolean,
Char = ElementType.Char,
SByte = ElementType.I1,
Byte = ElementType.U1,
Int16 = ElementType.I2,
UInt16 = ElementType.U2,
Int32 = ElementType.I4,
UInt32 = ElementType.U4,
Int64 = ElementType.I8,
UInt64 = ElementType.U8,
Single = ElementType.R4,
Double = ElementType.R8,
String = ElementType.String,
Pointer = ElementType.Ptr,
ByReference = ElementType.ByRef,
ValueType = ElementType.ValueType,
Class = ElementType.Class,
Var = ElementType.Var,
Array = ElementType.Array,
GenericInstance = ElementType.GenericInst,
TypedByReference = ElementType.TypedByRef,
IntPtr = ElementType.I,
UIntPtr = ElementType.U,
FunctionPointer = ElementType.FnPtr,
Object = ElementType.Object,
MVar = ElementType.MVar,
RequiredModifier = ElementType.CModReqD,
OptionalModifier = ElementType.CModOpt,
Sentinel = ElementType.Sentinel,
Pinned = ElementType.Pinned,
}
internal class TypeReference : MemberReference, IGenericParameterProvider, IGenericContext {
string @namespace;
bool value_type;
internal IMetadataScope scope;
internal ModuleDefinition module;
internal ElementType etype = ElementType.None;
string fullname;
protected Collection<GenericParameter> generic_parameters;
public override string Name {
get { return base.Name; }
set {
if (IsWindowsRuntimeProjection && value != base.Name)
throw new InvalidOperationException ("Projected type reference name can't be changed.");
base.Name = value;
ClearFullName ();
}
}
public virtual string Namespace {
get { return @namespace; }
set {
if (IsWindowsRuntimeProjection && value != @namespace)
throw new InvalidOperationException ("Projected type reference namespace can't be changed.");
@namespace = value;
ClearFullName ();
}
}
public virtual bool IsValueType {
get { return value_type; }
set { value_type = value; }
}
public override ModuleDefinition Module {
get {
if (module != null)
return module;
var declaring_type = this.DeclaringType;
if (declaring_type != null)
return declaring_type.Module;
return null;
}
}
internal new TypeReferenceProjection WindowsRuntimeProjection {
get { return (TypeReferenceProjection) projection; }
set { projection = value; }
}
IGenericParameterProvider IGenericContext.Type {
get { return this; }
}
IGenericParameterProvider IGenericContext.Method {
get { return null; }
}
GenericParameterType IGenericParameterProvider.GenericParameterType {
get { return GenericParameterType.Type; }
}
public virtual bool HasGenericParameters {
get { return !generic_parameters.IsNullOrEmpty (); }
}
public virtual Collection<GenericParameter> GenericParameters {
get {
if (generic_parameters != null)
return generic_parameters;
return generic_parameters = new GenericParameterCollection (this);
}
}
public virtual IMetadataScope Scope {
get {
var declaring_type = this.DeclaringType;
if (declaring_type != null)
return declaring_type.Scope;
return scope;
}
set {
var declaring_type = this.DeclaringType;
if (declaring_type != null) {
if (IsWindowsRuntimeProjection && value != declaring_type.Scope)
throw new InvalidOperationException ("Projected type scope can't be changed.");
declaring_type.Scope = value;
return;
}
if (IsWindowsRuntimeProjection && value != scope)
throw new InvalidOperationException ("Projected type scope can't be changed.");
scope = value;
}
}
public bool IsNested {
get { return this.DeclaringType != null; }
}
public override TypeReference DeclaringType {
get { return base.DeclaringType; }
set {
if (IsWindowsRuntimeProjection && value != base.DeclaringType)
throw new InvalidOperationException ("Projected type declaring type can't be changed.");
base.DeclaringType = value;
ClearFullName ();
}
}
public override string FullName {
get {
if (fullname != null)
return fullname;
fullname = this.TypeFullName ();
if (IsNested)
fullname = DeclaringType.FullName + "/" + fullname;
return fullname;
}
}
public virtual bool IsByReference {
get { return false; }
}
public virtual bool IsPointer {
get { return false; }
}
public virtual bool IsSentinel {
get { return false; }
}
public virtual bool IsArray {
get { return false; }
}
public virtual bool IsGenericParameter {
get { return false; }
}
public virtual bool IsGenericInstance {
get { return false; }
}
public virtual bool IsRequiredModifier {
get { return false; }
}
public virtual bool IsOptionalModifier {
get { return false; }
}
public virtual bool IsPinned {
get { return false; }
}
public virtual bool IsFunctionPointer {
get { return false; }
}
public virtual bool IsPrimitive {
get { return etype.IsPrimitive (); }
}
public virtual MetadataType MetadataType {
get {
switch (etype) {
case ElementType.None:
return IsValueType ? MetadataType.ValueType : MetadataType.Class;
default:
return (MetadataType) etype;
}
}
}
protected TypeReference (string @namespace, string name)
: base (name)
{
this.@namespace = @namespace ?? string.Empty;
this.token = new MetadataToken (TokenType.TypeRef, 0);
}
public TypeReference (string @namespace, string name, ModuleDefinition module, IMetadataScope scope)
: this (@namespace, name)
{
this.module = module;
this.scope = scope;
}
public TypeReference (string @namespace, string name, ModuleDefinition module, IMetadataScope scope, bool valueType) :
this (@namespace, name, module, scope)
{
value_type = valueType;
}
protected virtual void ClearFullName ()
{
this.fullname = null;
}
public virtual TypeReference GetElementType ()
{
return this;
}
protected override IMemberDefinition ResolveDefinition ()
{
return this.Resolve ();
}
public new virtual TypeDefinition Resolve ()
{
var module = this.Module;
if (module == null)
throw new NotSupportedException ();
return module.Resolve (this);
}
}
static partial class Mixin {
public static bool IsPrimitive (this ElementType self)
{
switch (self) {
case ElementType.Boolean:
case ElementType.Char:
case ElementType.I:
case ElementType.U:
case ElementType.I1:
case ElementType.U1:
case ElementType.I2:
case ElementType.U2:
case ElementType.I4:
case ElementType.U4:
case ElementType.I8:
case ElementType.U8:
case ElementType.R4:
case ElementType.R8:
return true;
default:
return false;
}
}
public static string TypeFullName (this TypeReference self)
{
return string.IsNullOrEmpty (self.Namespace)
? self.Name
: self.Namespace + '.' + self.Name;
}
public static bool IsTypeOf (this TypeReference self, string @namespace, string name)
{
return self.Name == name
&& self.Namespace == @namespace;
}
public static bool IsTypeSpecification (this TypeReference type)
{
switch (type.etype) {
case ElementType.Array:
case ElementType.ByRef:
case ElementType.CModOpt:
case ElementType.CModReqD:
case ElementType.FnPtr:
case ElementType.GenericInst:
case ElementType.MVar:
case ElementType.Pinned:
case ElementType.Ptr:
case ElementType.SzArray:
case ElementType.Sentinel:
case ElementType.Var:
return true;
}
return false;
}
public static TypeDefinition CheckedResolve (this TypeReference self)
{
var type = self.Resolve ();
if (type == null)
throw new ResolutionException (self);
return type;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Cecil.Metadata;
namespace Mono.Cecil {
internal abstract class TypeSpecification : TypeReference {
readonly TypeReference element_type;
public TypeReference ElementType {
get { return element_type; }
}
public override string Name {
get { return element_type.Name; }
set { throw new InvalidOperationException (); }
}
public override string Namespace {
get { return element_type.Namespace; }
set { throw new InvalidOperationException (); }
}
public override IMetadataScope Scope {
get { return element_type.Scope; }
set { throw new InvalidOperationException (); }
}
public override ModuleDefinition Module {
get { return element_type.Module; }
}
public override string FullName {
get { return element_type.FullName; }
}
public override bool ContainsGenericParameter {
get { return element_type.ContainsGenericParameter; }
}
public override MetadataType MetadataType {
get { return (MetadataType) etype; }
}
internal TypeSpecification (TypeReference type)
: base (null, null)
{
this.element_type = type;
this.token = new MetadataToken (TokenType.TypeSpec);
}
public override TypeReference GetElementType ()
{
return element_type.GetElementType ();
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Cecil.Metadata;
namespace Mono.Cecil {
internal abstract class TypeSystem {
sealed class CoreTypeSystem : TypeSystem {
public CoreTypeSystem (ModuleDefinition module)
: base (module)
{
}
internal override TypeReference LookupType (string @namespace, string name)
{
var type = LookupTypeDefinition (@namespace, name) ?? LookupTypeForwarded (@namespace, name);
if (type != null)
return type;
throw new NotSupportedException ();
}
TypeReference LookupTypeDefinition (string @namespace, string name)
{
var metadata = module.MetadataSystem;
if (metadata.Types == null)
Initialize (module.Types);
return module.Read (new Row<string, string> (@namespace, name), (row, reader) => {
var types = reader.metadata.Types;
for (int i = 0; i < types.Length; i++) {
if (types [i] == null)
types [i] = reader.GetTypeDefinition ((uint) i + 1);
var type = types [i];
if (type.Name == row.Col2 && type.Namespace == row.Col1)
return type;
}
return null;
});
}
TypeReference LookupTypeForwarded (string @namespace, string name)
{
if (!module.HasExportedTypes)
return null;
var exported_types = module.ExportedTypes;
for (int i = 0; i < exported_types.Count; i++) {
var exported_type = exported_types [i];
if (exported_type.Name == name && exported_type.Namespace == @namespace)
return exported_type.CreateReference ();
}
return null;
}
static void Initialize (object obj)
{
}
}
sealed class CommonTypeSystem : TypeSystem {
AssemblyNameReference core_library;
public CommonTypeSystem (ModuleDefinition module)
: base (module)
{
}
internal override TypeReference LookupType (string @namespace, string name)
{
return CreateTypeReference (@namespace, name);
}
public AssemblyNameReference GetCoreLibraryReference ()
{
if (core_library != null)
return core_library;
if (module.TryGetCoreLibraryReference (out core_library))
return core_library;
core_library = new AssemblyNameReference {
Name = Mixin.mscorlib,
Version = GetCorlibVersion (),
PublicKeyToken = new byte [] { 0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89 },
};
module.AssemblyReferences.Add (core_library);
return core_library;
}
Version GetCorlibVersion ()
{
switch (module.Runtime) {
case TargetRuntime.Net_1_0:
case TargetRuntime.Net_1_1:
return new Version (1, 0, 0, 0);
case TargetRuntime.Net_2_0:
return new Version (2, 0, 0, 0);
case TargetRuntime.Net_4_0:
return new Version (4, 0, 0, 0);
default:
throw new NotSupportedException ();
}
}
TypeReference CreateTypeReference (string @namespace, string name)
{
return new TypeReference (@namespace, name, module, GetCoreLibraryReference ());
}
}
readonly ModuleDefinition module;
TypeReference type_object;
TypeReference type_void;
TypeReference type_bool;
TypeReference type_char;
TypeReference type_sbyte;
TypeReference type_byte;
TypeReference type_int16;
TypeReference type_uint16;
TypeReference type_int32;
TypeReference type_uint32;
TypeReference type_int64;
TypeReference type_uint64;
TypeReference type_single;
TypeReference type_double;
TypeReference type_intptr;
TypeReference type_uintptr;
TypeReference type_string;
TypeReference type_typedref;
TypeSystem (ModuleDefinition module)
{
this.module = module;
}
internal static TypeSystem CreateTypeSystem (ModuleDefinition module)
{
if (module.IsCoreLibrary ())
return new CoreTypeSystem (module);
return new CommonTypeSystem (module);
}
internal abstract TypeReference LookupType (string @namespace, string name);
TypeReference LookupSystemType (ref TypeReference reference, string name, ElementType element_type)
{
lock (module.SyncRoot) {
if (reference != null)
return reference;
var type = LookupType ("System", name);
type.etype = element_type;
return reference = type;
}
}
TypeReference LookupSystemValueType (ref TypeReference typeRef, string name, ElementType element_type)
{
lock (module.SyncRoot) {
if (typeRef != null)
return typeRef;
var type = LookupType ("System", name);
type.etype = element_type;
type.KnownValueType ();
return typeRef = type;
}
}
[Obsolete ("Use CoreLibrary")]
public IMetadataScope Corlib {
get { return CoreLibrary; }
}
public IMetadataScope CoreLibrary {
get {
var common = this as CommonTypeSystem;
if (common == null)
return module;
return common.GetCoreLibraryReference ();
}
}
public TypeReference Object {
get { return type_object ?? (LookupSystemType (ref type_object, "Object", ElementType.Object)); }
}
public TypeReference Void {
get { return type_void ?? (LookupSystemType (ref type_void, "Void", ElementType.Void)); }
}
public TypeReference Boolean {
get { return type_bool ?? (LookupSystemValueType (ref type_bool, "Boolean", ElementType.Boolean)); }
}
public TypeReference Char {
get { return type_char ?? (LookupSystemValueType (ref type_char, "Char", ElementType.Char)); }
}
public TypeReference SByte {
get { return type_sbyte ?? (LookupSystemValueType (ref type_sbyte, "SByte", ElementType.I1)); }
}
public TypeReference Byte {
get { return type_byte ?? (LookupSystemValueType (ref type_byte, "Byte", ElementType.U1)); }
}
public TypeReference Int16 {
get { return type_int16 ?? (LookupSystemValueType (ref type_int16, "Int16", ElementType.I2)); }
}
public TypeReference UInt16 {
get { return type_uint16 ?? (LookupSystemValueType (ref type_uint16, "UInt16", ElementType.U2)); }
}
public TypeReference Int32 {
get { return type_int32 ?? (LookupSystemValueType (ref type_int32, "Int32", ElementType.I4)); }
}
public TypeReference UInt32 {
get { return type_uint32 ?? (LookupSystemValueType (ref type_uint32, "UInt32", ElementType.U4)); }
}
public TypeReference Int64 {
get { return type_int64 ?? (LookupSystemValueType (ref type_int64, "Int64", ElementType.I8)); }
}
public TypeReference UInt64 {
get { return type_uint64 ?? (LookupSystemValueType (ref type_uint64, "UInt64", ElementType.U8)); }
}
public TypeReference Single {
get { return type_single ?? (LookupSystemValueType (ref type_single, "Single", ElementType.R4)); }
}
public TypeReference Double {
get { return type_double ?? (LookupSystemValueType (ref type_double, "Double", ElementType.R8)); }
}
public TypeReference IntPtr {
get { return type_intptr ?? (LookupSystemValueType (ref type_intptr, "IntPtr", ElementType.I)); }
}
public TypeReference UIntPtr {
get { return type_uintptr ?? (LookupSystemValueType (ref type_uintptr, "UIntPtr", ElementType.U)); }
}
public TypeReference String {
get { return type_string ?? (LookupSystemType (ref type_string, "String", ElementType.String)); }
}
public TypeReference TypedReference {
get { return type_typedref ?? (LookupSystemValueType (ref type_typedref, "TypedReference", ElementType.TypedByRef)); }
}
}
static partial class Mixin {
public const string mscorlib = "mscorlib";
public const string system_runtime = "System.Runtime";
public const string system_private_corelib = "System.Private.CoreLib";
public const string netstandard = "netstandard";
public static bool TryGetCoreLibraryReference (this ModuleDefinition module, out AssemblyNameReference reference)
{
var references = module.AssemblyReferences;
for (int i = 0; i < references.Count; i++) {
reference = references [i];
if (IsCoreLibrary (reference))
return true;
}
reference = null;
return false;
}
public static bool IsCoreLibrary (this ModuleDefinition module)
{
if (module.Assembly == null)
return false;
if (!IsCoreLibrary (module.Assembly.Name))
return false;
if (module.HasImage && module.Read (module, (m, reader) => reader.image.GetTableLength (Table.AssemblyRef) > 0))
return false;
return true;
}
public static void KnownValueType (this TypeReference type)
{
if (!type.IsDefinition)
type.IsValueType = true;
}
static bool IsCoreLibrary (AssemblyNameReference reference)
{
var name = reference.Name;
return name == mscorlib
|| name == system_runtime
|| name == system_private_corelib
|| name == netstandard;
}
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil {
internal enum VariantType {
None = 0,
I2 = 2,
I4 = 3,
R4 = 4,
R8 = 5,
CY = 6,
Date = 7,
BStr = 8,
Dispatch = 9,
Error = 10,
Bool = 11,
Variant = 12,
Unknown = 13,
Decimal = 14,
I1 = 16,
UI1 = 17,
UI2 = 18,
UI4 = 19,
Int = 22,
UInt = 23
}
}
}
#endregion
#region Mono.Cecil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Collections.Generic;
using System.Threading;
using Mono.Collections.Generic;
namespace Mono.Cecil {
sealed class MemberReferenceProjection {
public readonly string Name;
public readonly MemberReferenceTreatment Treatment;
public MemberReferenceProjection (MemberReference member, MemberReferenceTreatment treatment)
{
Name = member.Name;
Treatment = treatment;
}
}
sealed class TypeDefinitionProjection {
public readonly TypeAttributes Attributes;
public readonly string Name;
public readonly TypeDefinitionTreatment Treatment;
public TypeDefinitionProjection (TypeDefinition type, TypeDefinitionTreatment treatment)
{
Attributes = type.Attributes;
Name = type.Name;
Treatment = treatment;
}
}
sealed class TypeReferenceProjection {
public readonly string Name;
public readonly string Namespace;
public readonly IMetadataScope Scope;
public readonly TypeReferenceTreatment Treatment;
public TypeReferenceProjection (TypeReference type, TypeReferenceTreatment treatment)
{
Name = type.Name;
Namespace = type.Namespace;
Scope = type.Scope;
Treatment = treatment;
}
}
sealed class MethodDefinitionProjection {
public readonly MethodAttributes Attributes;
public readonly MethodImplAttributes ImplAttributes;
public readonly string Name;
public readonly MethodDefinitionTreatment Treatment;
public MethodDefinitionProjection (MethodDefinition method, MethodDefinitionTreatment treatment)
{
Attributes = method.Attributes;
ImplAttributes = method.ImplAttributes;
Name = method.Name;
Treatment = treatment;
}
}
sealed class FieldDefinitionProjection {
public readonly FieldAttributes Attributes;
public readonly FieldDefinitionTreatment Treatment;
public FieldDefinitionProjection (FieldDefinition field, FieldDefinitionTreatment treatment)
{
Attributes = field.Attributes;
Treatment = treatment;
}
}
sealed class CustomAttributeValueProjection {
public readonly AttributeTargets Targets;
public readonly CustomAttributeValueTreatment Treatment;
public CustomAttributeValueProjection (AttributeTargets targets, CustomAttributeValueTreatment treatment)
{
Targets = targets;
Treatment = treatment;
}
}
sealed class WindowsRuntimeProjections {
struct ProjectionInfo {
public readonly string WinRTNamespace;
public readonly string ClrNamespace;
public readonly string ClrName;
public readonly string ClrAssembly;
public readonly bool Attribute;
public readonly bool Disposable;
public ProjectionInfo (string winrt_namespace, string clr_namespace, string clr_name, string clr_assembly, bool attribute = false, bool disposable = false)
{
WinRTNamespace = winrt_namespace;
ClrNamespace = clr_namespace;
ClrName = clr_name;
ClrAssembly = clr_assembly;
Attribute = attribute;
Disposable = disposable;
}
}
static readonly Version version = new Version (4, 0, 0, 0);
static readonly byte[] contract_pk_token = {
0xB0, 0x3F, 0x5F, 0x7F, 0x11, 0xD5, 0x0A, 0x3A
};
static readonly byte[] contract_pk = {
0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00,
0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
0x07, 0xD1, 0xFA, 0x57, 0xC4, 0xAE, 0xD9, 0xF0, 0xA3, 0x2E, 0x84, 0xAA, 0x0F, 0xAE, 0xFD, 0x0D,
0xE9, 0xE8, 0xFD, 0x6A, 0xEC, 0x8F, 0x87, 0xFB, 0x03, 0x76, 0x6C, 0x83, 0x4C, 0x99, 0x92, 0x1E,
0xB2, 0x3B, 0xE7, 0x9A, 0xD9, 0xD5, 0xDC, 0xC1, 0xDD, 0x9A, 0xD2, 0x36, 0x13, 0x21, 0x02, 0x90,
0x0B, 0x72, 0x3C, 0xF9, 0x80, 0x95, 0x7F, 0xC4, 0xE1, 0x77, 0x10, 0x8F, 0xC6, 0x07, 0x77, 0x4F,
0x29, 0xE8, 0x32, 0x0E, 0x92, 0xEA, 0x05, 0xEC, 0xE4, 0xE8, 0x21, 0xC0, 0xA5, 0xEF, 0xE8, 0xF1,
0x64, 0x5C, 0x4C, 0x0C, 0x93, 0xC1, 0xAB, 0x99, 0x28, 0x5D, 0x62, 0x2C, 0xAA, 0x65, 0x2C, 0x1D,
0xFA, 0xD6, 0x3D, 0x74, 0x5D, 0x6F, 0x2D, 0xE5, 0xF1, 0x7E, 0x5E, 0xAF, 0x0F, 0xC4, 0x96, 0x3D,
0x26, 0x1C, 0x8A, 0x12, 0x43, 0x65, 0x18, 0x20, 0x6D, 0xC0, 0x93, 0x34, 0x4D, 0x5A, 0xD2, 0x93
};
static Dictionary<string, ProjectionInfo> projections;
static Dictionary<string, ProjectionInfo> Projections
{
get {
if (projections != null)
return projections;
return projections = new Dictionary<string, ProjectionInfo> {
{ "AttributeTargets", new ProjectionInfo ("Windows.Foundation.Metadata", "System", "AttributeTargets", "System.Runtime") },
{ "AttributeUsageAttribute", new ProjectionInfo ("Windows.Foundation.Metadata", "System", "AttributeUsageAttribute", "System.Runtime", attribute: true) },
{ "Color", new ProjectionInfo ("Windows.UI", "Windows.UI", "Color", "System.Runtime.WindowsRuntime") },
{ "CornerRadius", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "CornerRadius", "System.Runtime.WindowsRuntime.UI.Xaml") },
{ "DateTime", new ProjectionInfo ("Windows.Foundation", "System", "DateTimeOffset", "System.Runtime") },
{ "Duration", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "Duration", "System.Runtime.WindowsRuntime.UI.Xaml") },
{ "DurationType", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "DurationType", "System.Runtime.WindowsRuntime.UI.Xaml") },
{ "EventHandler`1", new ProjectionInfo ("Windows.Foundation", "System", "EventHandler`1", "System.Runtime") },
{ "EventRegistrationToken", new ProjectionInfo ("Windows.Foundation", "System.Runtime.InteropServices.WindowsRuntime", "EventRegistrationToken", "System.Runtime.InteropServices.WindowsRuntime") },
{ "GeneratorPosition", new ProjectionInfo ("Windows.UI.Xaml.Controls.Primitives", "Windows.UI.Xaml.Controls.Primitives", "GeneratorPosition", "System.Runtime.WindowsRuntime.UI.Xaml") },
{ "GridLength", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "GridLength", "System.Runtime.WindowsRuntime.UI.Xaml") },
{ "GridUnitType", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "GridUnitType", "System.Runtime.WindowsRuntime.UI.Xaml") },
{ "HResult", new ProjectionInfo ("Windows.Foundation", "System", "Exception", "System.Runtime") },
{ "IBindableIterable", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections", "IEnumerable", "System.Runtime") },
{ "IBindableVector", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections", "IList", "System.Runtime") },
{ "IClosable", new ProjectionInfo ("Windows.Foundation", "System", "IDisposable", "System.Runtime", disposable: true) },
{ "ICommand", new ProjectionInfo ("Windows.UI.Xaml.Input", "System.Windows.Input", "ICommand", "System.ObjectModel") },
{ "IIterable`1", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IEnumerable`1", "System.Runtime") },
{ "IKeyValuePair`2", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "KeyValuePair`2", "System.Runtime") },
{ "IMapView`2", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IReadOnlyDictionary`2", "System.Runtime") },
{ "IMap`2", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IDictionary`2", "System.Runtime") },
{ "INotifyCollectionChanged", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections.Specialized", "INotifyCollectionChanged", "System.ObjectModel") },
{ "INotifyPropertyChanged", new ProjectionInfo ("Windows.UI.Xaml.Data", "System.ComponentModel", "INotifyPropertyChanged", "System.ObjectModel") },
{ "IReference`1", new ProjectionInfo ("Windows.Foundation", "System", "Nullable`1", "System.Runtime") },
{ "IVectorView`1", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IReadOnlyList`1", "System.Runtime") },
{ "IVector`1", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IList`1", "System.Runtime") },
{ "KeyTime", new ProjectionInfo ("Windows.UI.Xaml.Media.Animation", "Windows.UI.Xaml.Media.Animation", "KeyTime", "System.Runtime.WindowsRuntime.UI.Xaml") },
{ "Matrix", new ProjectionInfo ("Windows.UI.Xaml.Media", "Windows.UI.Xaml.Media", "Matrix", "System.Runtime.WindowsRuntime.UI.Xaml") },
{ "Matrix3D", new ProjectionInfo ("Windows.UI.Xaml.Media.Media3D", "Windows.UI.Xaml.Media.Media3D", "Matrix3D", "System.Runtime.WindowsRuntime.UI.Xaml") },
{ "Matrix3x2", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Matrix3x2", "System.Numerics.Vectors") },
{ "Matrix4x4", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Matrix4x4", "System.Numerics.Vectors") },
{ "NotifyCollectionChangedAction", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections.Specialized", "NotifyCollectionChangedAction", "System.ObjectModel") },
{ "NotifyCollectionChangedEventArgs", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections.Specialized", "NotifyCollectionChangedEventArgs", "System.ObjectModel") },
{ "NotifyCollectionChangedEventHandler", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections.Specialized", "NotifyCollectionChangedEventHandler", "System.ObjectModel") },
{ "Plane", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Plane", "System.Numerics.Vectors") },
{ "Point", new ProjectionInfo ("Windows.Foundation", "Windows.Foundation", "Point", "System.Runtime.WindowsRuntime") },
{ "PropertyChangedEventArgs", new ProjectionInfo ("Windows.UI.Xaml.Data", "System.ComponentModel", "PropertyChangedEventArgs", "System.ObjectModel") },
{ "PropertyChangedEventHandler", new ProjectionInfo ("Windows.UI.Xaml.Data", "System.ComponentModel", "PropertyChangedEventHandler", "System.ObjectModel") },
{ "Quaternion", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Quaternion", "System.Numerics.Vectors") },
{ "Rect", new ProjectionInfo ("Windows.Foundation", "Windows.Foundation", "Rect", "System.Runtime.WindowsRuntime") },
{ "RepeatBehavior", new ProjectionInfo ("Windows.UI.Xaml.Media.Animation", "Windows.UI.Xaml.Media.Animation", "RepeatBehavior", "System.Runtime.WindowsRuntime.UI.Xaml") },
{ "RepeatBehaviorType", new ProjectionInfo ("Windows.UI.Xaml.Media.Animation", "Windows.UI.Xaml.Media.Animation", "RepeatBehaviorType", "System.Runtime.WindowsRuntime.UI.Xaml") },
{ "Size", new ProjectionInfo ("Windows.Foundation", "Windows.Foundation", "Size", "System.Runtime.WindowsRuntime") },
{ "Thickness", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "Thickness", "System.Runtime.WindowsRuntime.UI.Xaml") },
{ "TimeSpan", new ProjectionInfo ("Windows.Foundation", "System", "TimeSpan", "System.Runtime") },
{ "TypeName", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System", "Type", "System.Runtime") },
{ "Uri", new ProjectionInfo ("Windows.Foundation", "System", "Uri", "System.Runtime") },
{ "Vector2", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Vector2", "System.Numerics.Vectors") },
{ "Vector3", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Vector3", "System.Numerics.Vectors") },
{ "Vector4", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Vector4", "System.Numerics.Vectors") },
};
}
}
readonly ModuleDefinition module;
Version corlib_version = new Version (255, 255, 255, 255);
AssemblyNameReference[] virtual_references;
AssemblyNameReference[] VirtualReferences {
get {
if (virtual_references == null) {
// force module to read its assembly references. that will in turn initialize virtual_references
Mixin.Read (module.AssemblyReferences);
}
return virtual_references;
}
}
public WindowsRuntimeProjections (ModuleDefinition module)
{
this.module = module;
}
public static void Project (TypeDefinition type)
{
var treatment = TypeDefinitionTreatment.None;
var metadata_kind = type.Module.MetadataKind;
if (type.IsWindowsRuntime) {
if (metadata_kind == MetadataKind.WindowsMetadata) {
treatment = GetWellKnownTypeDefinitionTreatment (type);
if (treatment != TypeDefinitionTreatment.None) {
ApplyProjection (type, new TypeDefinitionProjection (type, treatment));
return;
}
var base_type = type.BaseType;
if (base_type != null && IsAttribute (base_type))
treatment = TypeDefinitionTreatment.NormalAttribute;
else
treatment = TypeDefinitionTreatment.NormalType;
}
else if (metadata_kind == MetadataKind.ManagedWindowsMetadata && NeedsWindowsRuntimePrefix (type))
treatment = TypeDefinitionTreatment.PrefixWindowsRuntimeName;
if (treatment == TypeDefinitionTreatment.PrefixWindowsRuntimeName || treatment == TypeDefinitionTreatment.NormalType)
if (!type.IsInterface && HasAttribute (type, "Windows.UI.Xaml", "TreatAsAbstractComposableClassAttribute"))
treatment |= TypeDefinitionTreatment.Abstract;
}
else if (metadata_kind == MetadataKind.ManagedWindowsMetadata && IsClrImplementationType (type))
treatment = TypeDefinitionTreatment.UnmangleWindowsRuntimeName;
if (treatment != TypeDefinitionTreatment.None)
ApplyProjection (type, new TypeDefinitionProjection (type, treatment));
}
static TypeDefinitionTreatment GetWellKnownTypeDefinitionTreatment (TypeDefinition type)
{
ProjectionInfo info;
if (!Projections.TryGetValue (type.Name, out info))
return TypeDefinitionTreatment.None;
var treatment = info.Attribute ? TypeDefinitionTreatment.RedirectToClrAttribute : TypeDefinitionTreatment.RedirectToClrType;
if (type.Namespace == info.ClrNamespace)
return treatment;
if (type.Namespace == info.WinRTNamespace)
return treatment | TypeDefinitionTreatment.Internal;
return TypeDefinitionTreatment.None;
}
static bool NeedsWindowsRuntimePrefix (TypeDefinition type)
{
if ((type.Attributes & (TypeAttributes.VisibilityMask | TypeAttributes.Interface)) != TypeAttributes.Public)
return false;
var base_type = type.BaseType;
if (base_type == null || base_type.MetadataToken.TokenType != TokenType.TypeRef)
return false;
if (base_type.Namespace == "System")
switch (base_type.Name)
{
case "Attribute":
case "MulticastDelegate":
case "ValueType":
return false;
}
return true;
}
static bool IsClrImplementationType (TypeDefinition type)
{
if ((type.Attributes & (TypeAttributes.VisibilityMask | TypeAttributes.SpecialName)) != TypeAttributes.SpecialName)
return false;
return type.Name.StartsWith ("<CLR>");
}
public static void ApplyProjection (TypeDefinition type, TypeDefinitionProjection projection)
{
if (projection == null)
return;
var treatment = projection.Treatment;
switch (treatment & TypeDefinitionTreatment.KindMask) {
case TypeDefinitionTreatment.NormalType:
type.Attributes |= TypeAttributes.WindowsRuntime | TypeAttributes.Import;
break;
case TypeDefinitionTreatment.NormalAttribute:
type.Attributes |= TypeAttributes.WindowsRuntime | TypeAttributes.Sealed;
break;
case TypeDefinitionTreatment.UnmangleWindowsRuntimeName:
type.Attributes = type.Attributes & ~TypeAttributes.SpecialName | TypeAttributes.Public;
type.Name = type.Name.Substring ("<CLR>".Length);
break;
case TypeDefinitionTreatment.PrefixWindowsRuntimeName:
type.Attributes = type.Attributes & ~TypeAttributes.Public | TypeAttributes.Import;
type.Name = "<WinRT>" + type.Name;
break;
case TypeDefinitionTreatment.RedirectToClrType:
type.Attributes = type.Attributes & ~TypeAttributes.Public | TypeAttributes.Import;
break;
case TypeDefinitionTreatment.RedirectToClrAttribute:
type.Attributes = type.Attributes & ~TypeAttributes.Public;
break;
}
if ((treatment & TypeDefinitionTreatment.Abstract) != 0)
type.Attributes |= TypeAttributes.Abstract;
if ((treatment & TypeDefinitionTreatment.Internal) != 0)
type.Attributes &= ~TypeAttributes.Public;
type.WindowsRuntimeProjection = projection;
}
public static TypeDefinitionProjection RemoveProjection (TypeDefinition type)
{
if (!type.IsWindowsRuntimeProjection)
return null;
var projection = type.WindowsRuntimeProjection;
type.WindowsRuntimeProjection = null;
type.Attributes = projection.Attributes;
type.Name = projection.Name;
return projection;
}
public static void Project (TypeReference type)
{
TypeReferenceTreatment treatment;
ProjectionInfo info;
if (Projections.TryGetValue (type.Name, out info) && info.WinRTNamespace == type.Namespace)
treatment = TypeReferenceTreatment.UseProjectionInfo;
else
treatment = GetSpecialTypeReferenceTreatment (type);
if (treatment != TypeReferenceTreatment.None)
ApplyProjection (type, new TypeReferenceProjection (type, treatment));
}
static TypeReferenceTreatment GetSpecialTypeReferenceTreatment (TypeReference type)
{
if (type.Namespace == "System") {
if (type.Name == "MulticastDelegate")
return TypeReferenceTreatment.SystemDelegate;
if (type.Name == "Attribute")
return TypeReferenceTreatment.SystemAttribute;
}
return TypeReferenceTreatment.None;
}
static bool IsAttribute (TypeReference type)
{
if (type.MetadataToken.TokenType != TokenType.TypeRef)
return false;
return type.Name == "Attribute" && type.Namespace == "System";
}
static bool IsEnum (TypeReference type)
{
if (type.MetadataToken.TokenType != TokenType.TypeRef)
return false;
return type.Name == "Enum" && type.Namespace == "System";
}
public static void ApplyProjection (TypeReference type, TypeReferenceProjection projection)
{
if (projection == null)
return;
switch (projection.Treatment)
{
case TypeReferenceTreatment.SystemDelegate:
case TypeReferenceTreatment.SystemAttribute:
type.Scope = type.Module.Projections.GetAssemblyReference ("System.Runtime");
break;
case TypeReferenceTreatment.UseProjectionInfo:
var info = Projections [type.Name];
type.Name = info.ClrName;
type.Namespace = info.ClrNamespace;
type.Scope = type.Module.Projections.GetAssemblyReference (info.ClrAssembly);
break;
}
type.WindowsRuntimeProjection = projection;
}
public static TypeReferenceProjection RemoveProjection (TypeReference type)
{
if (!type.IsWindowsRuntimeProjection)
return null;
var projection = type.WindowsRuntimeProjection;
type.WindowsRuntimeProjection = null;
type.Name = projection.Name;
type.Namespace = projection.Namespace;
type.Scope = projection.Scope;
return projection;
}
public static void Project (MethodDefinition method)
{
var treatment = MethodDefinitionTreatment.None;
var other = false;
var declaring_type = method.DeclaringType;
if (declaring_type.IsWindowsRuntime)
{
if (IsClrImplementationType (declaring_type))
treatment = MethodDefinitionTreatment.None;
else if (declaring_type.IsNested)
treatment = MethodDefinitionTreatment.None;
else if (declaring_type.IsInterface)
treatment = MethodDefinitionTreatment.Runtime | MethodDefinitionTreatment.InternalCall;
else if (declaring_type.Module.MetadataKind == MetadataKind.ManagedWindowsMetadata && !method.IsPublic)
treatment = MethodDefinitionTreatment.None;
else
{
other = true;
var base_type = declaring_type.BaseType;
if (base_type != null && base_type.MetadataToken.TokenType == TokenType.TypeRef)
{
switch (GetSpecialTypeReferenceTreatment(base_type))
{
case TypeReferenceTreatment.SystemDelegate:
treatment = MethodDefinitionTreatment.Runtime | MethodDefinitionTreatment.Public;
other = false;
break;
case TypeReferenceTreatment.SystemAttribute:
treatment = MethodDefinitionTreatment.Runtime | MethodDefinitionTreatment.InternalCall;
other = false;
break;
}
}
}
}
if (other)
{
var seen_redirected = false;
var seen_non_redirected = false;
var disposable = false;
foreach (var @override in method.Overrides)
{
if (@override.MetadataToken.TokenType == TokenType.MemberRef && ImplementsRedirectedInterface (@override, out disposable))
{
seen_redirected = true;
if (disposable)
break;
}
else
seen_non_redirected = true;
}
if (disposable)
{
treatment = MethodDefinitionTreatment.Dispose;
other = false;
}
else if (seen_redirected && !seen_non_redirected)
{
treatment = MethodDefinitionTreatment.Runtime | MethodDefinitionTreatment.InternalCall | MethodDefinitionTreatment.Private;
other = false;
}
}
if (other)
treatment |= GetMethodDefinitionTreatmentFromCustomAttributes(method);
if (treatment != MethodDefinitionTreatment.None)
ApplyProjection (method, new MethodDefinitionProjection (method, treatment));
}
static MethodDefinitionTreatment GetMethodDefinitionTreatmentFromCustomAttributes(MethodDefinition method)
{
var treatment = MethodDefinitionTreatment.None;
foreach (var attribute in method.CustomAttributes)
{
var type = attribute.AttributeType;
if (type.Namespace != "Windows.UI.Xaml")
continue;
if (type.Name == "TreatAsPublicMethodAttribute")
treatment |= MethodDefinitionTreatment.Public;
else if (type.Name == "TreatAsAbstractMethodAttribute")
treatment |= MethodDefinitionTreatment.Abstract;
}
return treatment;
}
public static void ApplyProjection (MethodDefinition method, MethodDefinitionProjection projection)
{
if (projection == null)
return;
var treatment = projection.Treatment;
if ((treatment & MethodDefinitionTreatment.Dispose) != 0)
method.Name = "Dispose";
if ((treatment & MethodDefinitionTreatment.Abstract) != 0)
method.Attributes |= MethodAttributes.Abstract;
if ((treatment & MethodDefinitionTreatment.Private) != 0)
method.Attributes = (method.Attributes & ~MethodAttributes.MemberAccessMask) | MethodAttributes.Private;
if ((treatment & MethodDefinitionTreatment.Public) != 0)
method.Attributes = (method.Attributes & ~MethodAttributes.MemberAccessMask) | MethodAttributes.Public;
if ((treatment & MethodDefinitionTreatment.Runtime) != 0)
method.ImplAttributes |= MethodImplAttributes.Runtime;
if ((treatment & MethodDefinitionTreatment.InternalCall) != 0)
method.ImplAttributes |= MethodImplAttributes.InternalCall;
method.WindowsRuntimeProjection = projection;
}
public static MethodDefinitionProjection RemoveProjection (MethodDefinition method)
{
if (!method.IsWindowsRuntimeProjection)
return null;
var projection = method.WindowsRuntimeProjection;
method.WindowsRuntimeProjection = null;
method.Attributes = projection.Attributes;
method.ImplAttributes = projection.ImplAttributes;
method.Name = projection.Name;
return projection;
}
public static void Project (FieldDefinition field)
{
var treatment = FieldDefinitionTreatment.None;
var declaring_type = field.DeclaringType;
if (declaring_type.Module.MetadataKind == MetadataKind.WindowsMetadata && field.IsRuntimeSpecialName && field.Name == "value__") {
var base_type = declaring_type.BaseType;
if (base_type != null && IsEnum (base_type))
treatment = FieldDefinitionTreatment.Public;
}
if (treatment != FieldDefinitionTreatment.None)
ApplyProjection (field, new FieldDefinitionProjection (field, treatment));
}
public static void ApplyProjection (FieldDefinition field, FieldDefinitionProjection projection)
{
if (projection == null)
return;
if (projection.Treatment == FieldDefinitionTreatment.Public)
field.Attributes = (field.Attributes & ~FieldAttributes.FieldAccessMask) | FieldAttributes.Public;
field.WindowsRuntimeProjection = projection;
}
public static FieldDefinitionProjection RemoveProjection (FieldDefinition field)
{
if (!field.IsWindowsRuntimeProjection)
return null;
var projection = field.WindowsRuntimeProjection;
field.WindowsRuntimeProjection = null;
field.Attributes = projection.Attributes;
return projection;
}
public static void Project (MemberReference member)
{
bool disposable;
if (!ImplementsRedirectedInterface (member, out disposable) || !disposable)
return;
ApplyProjection (member, new MemberReferenceProjection (member, MemberReferenceTreatment.Dispose));
}
static bool ImplementsRedirectedInterface (MemberReference member, out bool disposable)
{
disposable = false;
var declaring_type = member.DeclaringType;
TypeReference type;
switch (declaring_type.MetadataToken.TokenType) {
case TokenType.TypeRef:
type = declaring_type;
break;
case TokenType.TypeSpec:
if (!declaring_type.IsGenericInstance)
return false;
type = ((TypeSpecification) declaring_type).ElementType;
if (type.MetadataType != MetadataType.Class || type.MetadataToken.TokenType != TokenType.TypeRef)
return false;
break;
default:
return false;
}
var projection = RemoveProjection (type);
var found = false;
ProjectionInfo info;
if (Projections.TryGetValue (type.Name, out info) && type.Namespace == info.WinRTNamespace) {
disposable = info.Disposable;
found = true;
}
ApplyProjection (type, projection);
return found;
}
public static void ApplyProjection (MemberReference member, MemberReferenceProjection projection)
{
if (projection == null)
return;
if (projection.Treatment == MemberReferenceTreatment.Dispose)
member.Name = "Dispose";
member.WindowsRuntimeProjection = projection;
}
public static MemberReferenceProjection RemoveProjection (MemberReference member)
{
if (!member.IsWindowsRuntimeProjection)
return null;
var projection = member.WindowsRuntimeProjection;
member.WindowsRuntimeProjection = null;
member.Name = projection.Name;
return projection;
}
public void AddVirtualReferences (Collection<AssemblyNameReference> references)
{
var corlib = GetCoreLibrary (references);
corlib_version = corlib.Version;
corlib.Version = version;
if (virtual_references == null) {
var winrt_references = GetAssemblyReferences (corlib);
Interlocked.CompareExchange (ref virtual_references, winrt_references, null);
}
foreach (var reference in virtual_references)
references.Add (reference);
}
public void RemoveVirtualReferences (Collection<AssemblyNameReference> references)
{
var corlib = GetCoreLibrary (references);
corlib.Version = corlib_version;
foreach (var reference in VirtualReferences)
references.Remove (reference);
}
static AssemblyNameReference[] GetAssemblyReferences (AssemblyNameReference corlib)
{
var system_runtime = new AssemblyNameReference ("System.Runtime", version);
var system_runtime_interopservices_windowsruntime = new AssemblyNameReference ("System.Runtime.InteropServices.WindowsRuntime", version);
var system_objectmodel = new AssemblyNameReference ("System.ObjectModel", version);
var system_runtime_windowsruntime = new AssemblyNameReference ("System.Runtime.WindowsRuntime", version);
var system_runtime_windowsruntime_ui_xaml = new AssemblyNameReference ("System.Runtime.WindowsRuntime.UI.Xaml", version);
var system_numerics_vectors = new AssemblyNameReference ("System.Numerics.Vectors", version);
if (corlib.HasPublicKey) {
system_runtime_windowsruntime.PublicKey =
system_runtime_windowsruntime_ui_xaml.PublicKey = corlib.PublicKey;
system_runtime.PublicKey =
system_runtime_interopservices_windowsruntime.PublicKey =
system_objectmodel.PublicKey =
system_numerics_vectors.PublicKey = contract_pk;
}
else {
system_runtime_windowsruntime.PublicKeyToken =
system_runtime_windowsruntime_ui_xaml.PublicKeyToken = corlib.PublicKeyToken;
system_runtime.PublicKeyToken =
system_runtime_interopservices_windowsruntime.PublicKeyToken =
system_objectmodel.PublicKeyToken =
system_numerics_vectors.PublicKeyToken = contract_pk_token;
}
return new[] {
system_runtime,
system_runtime_interopservices_windowsruntime,
system_objectmodel,
system_runtime_windowsruntime,
system_runtime_windowsruntime_ui_xaml,
system_numerics_vectors,
};
}
static AssemblyNameReference GetCoreLibrary (Collection<AssemblyNameReference> references)
{
foreach (var reference in references)
if (reference.Name == "mscorlib")
return reference;
throw new BadImageFormatException ("Missing mscorlib reference in AssemblyRef table.");
}
AssemblyNameReference GetAssemblyReference (string name)
{
foreach (var assembly in VirtualReferences)
if (assembly.Name == name)
return assembly;
throw new Exception ();
}
public static void Project (ICustomAttributeProvider owner, CustomAttribute attribute)
{
if (!IsWindowsAttributeUsageAttribute (owner, attribute))
return;
var treatment = CustomAttributeValueTreatment.None;
var type = (TypeDefinition) owner;
if (type.Namespace == "Windows.Foundation.Metadata") {
if (type.Name == "VersionAttribute")
treatment = CustomAttributeValueTreatment.VersionAttribute;
else if (type.Name == "DeprecatedAttribute")
treatment = CustomAttributeValueTreatment.DeprecatedAttribute;
}
if (treatment == CustomAttributeValueTreatment.None) {
var multiple = HasAttribute (type, "Windows.Foundation.Metadata", "AllowMultipleAttribute");
treatment = multiple ? CustomAttributeValueTreatment.AllowMultiple : CustomAttributeValueTreatment.AllowSingle;
}
if (treatment != CustomAttributeValueTreatment.None) {
var attribute_targets = (AttributeTargets) attribute.ConstructorArguments [0].Value;
ApplyProjection (attribute, new CustomAttributeValueProjection (attribute_targets, treatment));
}
}
static bool IsWindowsAttributeUsageAttribute (ICustomAttributeProvider owner, CustomAttribute attribute)
{
if (owner.MetadataToken.TokenType != TokenType.TypeDef)
return false;
var constructor = attribute.Constructor;
if (constructor.MetadataToken.TokenType != TokenType.MemberRef)
return false;
var declaring_type = constructor.DeclaringType;
if (declaring_type.MetadataToken.TokenType != TokenType.TypeRef)
return false;
// declaring type is already projected
return declaring_type.Name == "AttributeUsageAttribute" && declaring_type.Namespace == /*"Windows.Foundation.Metadata"*/"System";
}
static bool HasAttribute (TypeDefinition type, string @namespace, string name)
{
foreach (var attribute in type.CustomAttributes) {
var attribute_type = attribute.AttributeType;
if (attribute_type.Name == name && attribute_type.Namespace == @namespace)
return true;
}
return false;
}
public static void ApplyProjection (CustomAttribute attribute, CustomAttributeValueProjection projection)
{
if (projection == null)
return;
bool version_or_deprecated;
bool multiple;
switch (projection.Treatment) {
case CustomAttributeValueTreatment.AllowSingle:
version_or_deprecated = false;
multiple = false;
break;
case CustomAttributeValueTreatment.AllowMultiple:
version_or_deprecated = false;
multiple = true;
break;
case CustomAttributeValueTreatment.VersionAttribute:
case CustomAttributeValueTreatment.DeprecatedAttribute:
version_or_deprecated = true;
multiple = true;
break;
default:
throw new ArgumentException ();
}
var attribute_targets = (AttributeTargets) attribute.ConstructorArguments [0].Value;
if (version_or_deprecated)
attribute_targets |= AttributeTargets.Constructor | AttributeTargets.Property;
attribute.ConstructorArguments [0] = new CustomAttributeArgument (attribute.ConstructorArguments [0].Type, attribute_targets);
attribute.Properties.Add (new CustomAttributeNamedArgument ("AllowMultiple", new CustomAttributeArgument (attribute.Module.TypeSystem.Boolean, multiple)));
attribute.projection = projection;
}
public static CustomAttributeValueProjection RemoveProjection (CustomAttribute attribute)
{
if (attribute.projection == null)
return null;
var projection = attribute.projection;
attribute.projection = null;
attribute.ConstructorArguments [0] = new CustomAttributeArgument (attribute.ConstructorArguments [0].Type, projection.Targets);
attribute.Properties.Clear ();
return projection;
}
}
}
}
#endregion
#region Mono.Cecil.Cil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil.Cil {
internal enum Code {
Nop,
Break,
Ldarg_0,
Ldarg_1,
Ldarg_2,
Ldarg_3,
Ldloc_0,
Ldloc_1,
Ldloc_2,
Ldloc_3,
Stloc_0,
Stloc_1,
Stloc_2,
Stloc_3,
Ldarg_S,
Ldarga_S,
Starg_S,
Ldloc_S,
Ldloca_S,
Stloc_S,
Ldnull,
Ldc_I4_M1,
Ldc_I4_0,
Ldc_I4_1,
Ldc_I4_2,
Ldc_I4_3,
Ldc_I4_4,
Ldc_I4_5,
Ldc_I4_6,
Ldc_I4_7,
Ldc_I4_8,
Ldc_I4_S,
Ldc_I4,
Ldc_I8,
Ldc_R4,
Ldc_R8,
Dup,
Pop,
Jmp,
Call,
Calli,
Ret,
Br_S,
Brfalse_S,
Brtrue_S,
Beq_S,
Bge_S,
Bgt_S,
Ble_S,
Blt_S,
Bne_Un_S,
Bge_Un_S,
Bgt_Un_S,
Ble_Un_S,
Blt_Un_S,
Br,
Brfalse,
Brtrue,
Beq,
Bge,
Bgt,
Ble,
Blt,
Bne_Un,
Bge_Un,
Bgt_Un,
Ble_Un,
Blt_Un,
Switch,
Ldind_I1,
Ldind_U1,
Ldind_I2,
Ldind_U2,
Ldind_I4,
Ldind_U4,
Ldind_I8,
Ldind_I,
Ldind_R4,
Ldind_R8,
Ldind_Ref,
Stind_Ref,
Stind_I1,
Stind_I2,
Stind_I4,
Stind_I8,
Stind_R4,
Stind_R8,
Add,
Sub,
Mul,
Div,
Div_Un,
Rem,
Rem_Un,
And,
Or,
Xor,
Shl,
Shr,
Shr_Un,
Neg,
Not,
Conv_I1,
Conv_I2,
Conv_I4,
Conv_I8,
Conv_R4,
Conv_R8,
Conv_U4,
Conv_U8,
Callvirt,
Cpobj,
Ldobj,
Ldstr,
Newobj,
Castclass,
Isinst,
Conv_R_Un,
Unbox,
Throw,
Ldfld,
Ldflda,
Stfld,
Ldsfld,
Ldsflda,
Stsfld,
Stobj,
Conv_Ovf_I1_Un,
Conv_Ovf_I2_Un,
Conv_Ovf_I4_Un,
Conv_Ovf_I8_Un,
Conv_Ovf_U1_Un,
Conv_Ovf_U2_Un,
Conv_Ovf_U4_Un,
Conv_Ovf_U8_Un,
Conv_Ovf_I_Un,
Conv_Ovf_U_Un,
Box,
Newarr,
Ldlen,
Ldelema,
Ldelem_I1,
Ldelem_U1,
Ldelem_I2,
Ldelem_U2,
Ldelem_I4,
Ldelem_U4,
Ldelem_I8,
Ldelem_I,
Ldelem_R4,
Ldelem_R8,
Ldelem_Ref,
Stelem_I,
Stelem_I1,
Stelem_I2,
Stelem_I4,
Stelem_I8,
Stelem_R4,
Stelem_R8,
Stelem_Ref,
Ldelem_Any,
Stelem_Any,
Unbox_Any,
Conv_Ovf_I1,
Conv_Ovf_U1,
Conv_Ovf_I2,
Conv_Ovf_U2,
Conv_Ovf_I4,
Conv_Ovf_U4,
Conv_Ovf_I8,
Conv_Ovf_U8,
Refanyval,
Ckfinite,
Mkrefany,
Ldtoken,
Conv_U2,
Conv_U1,
Conv_I,
Conv_Ovf_I,
Conv_Ovf_U,
Add_Ovf,
Add_Ovf_Un,
Mul_Ovf,
Mul_Ovf_Un,
Sub_Ovf,
Sub_Ovf_Un,
Endfinally,
Leave,
Leave_S,
Stind_I,
Conv_U,
Arglist,
Ceq,
Cgt,
Cgt_Un,
Clt,
Clt_Un,
Ldftn,
Ldvirtftn,
Ldarg,
Ldarga,
Starg,
Ldloc,
Ldloca,
Stloc,
Localloc,
Endfilter,
Unaligned,
Volatile,
Tail,
Initobj,
Constrained,
Cpblk,
Initblk,
No,
Rethrow,
Sizeof,
Refanytype,
Readonly,
}
}
}
#endregion
#region Mono.Cecil.Cil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Cecil.PE;
using Mono.Collections.Generic;
using RVA = System.UInt32;
namespace Mono.Cecil.Cil {
sealed class CodeReader : BinaryStreamReader {
readonly internal MetadataReader reader;
int start;
MethodDefinition method;
MethodBody body;
int Offset {
get { return Position - start; }
}
public CodeReader (MetadataReader reader)
: base (reader.image.Stream.value)
{
this.reader = reader;
}
public int MoveTo (MethodDefinition method)
{
this.method = method;
this.reader.context = method;
var position = this.Position;
this.Position = (int) reader.image.ResolveVirtualAddress ((uint) method.RVA);
return position;
}
public void MoveBackTo (int position)
{
this.reader.context = null;
this.Position = position;
}
public MethodBody ReadMethodBody (MethodDefinition method)
{
var position = MoveTo (method);
this.body = new MethodBody (method);
ReadMethodBody ();
MoveBackTo (position);
return this.body;
}
public int ReadCodeSize (MethodDefinition method)
{
var position = MoveTo (method);
var code_size = ReadCodeSize ();
MoveBackTo (position);
return code_size;
}
int ReadCodeSize ()
{
var flags = ReadByte ();
switch (flags & 0x3) {
case 0x2: // tiny
return flags >> 2;
case 0x3: // fat
Advance (-1 + 2 + 2); // go back, 2 bytes flags, 2 bytes stack size
return (int) ReadUInt32 ();
default:
throw new InvalidOperationException ();
}
}
void ReadMethodBody ()
{
var flags = ReadByte ();
switch (flags & 0x3) {
case 0x2: // tiny
body.code_size = flags >> 2;
body.MaxStackSize = 8;
ReadCode ();
break;
case 0x3: // fat
Advance (-1);
ReadFatMethod ();
break;
default:
throw new InvalidOperationException ();
}
var symbol_reader = reader.module.symbol_reader;
if (symbol_reader != null && method.debug_info == null)
method.debug_info = symbol_reader.Read (method);
if (method.debug_info != null)
ReadDebugInfo ();
}
void ReadFatMethod ()
{
var flags = ReadUInt16 ();
body.max_stack_size = ReadUInt16 ();
body.code_size = (int) ReadUInt32 ();
body.local_var_token = new MetadataToken (ReadUInt32 ());
body.init_locals = (flags & 0x10) != 0;
if (body.local_var_token.RID != 0)
body.variables = ReadVariables (body.local_var_token);
ReadCode ();
if ((flags & 0x8) != 0)
ReadSection ();
}
public VariableDefinitionCollection ReadVariables (MetadataToken local_var_token)
{
var position = reader.position;
var variables = reader.ReadVariables (local_var_token);
reader.position = position;
return variables;
}
void ReadCode ()
{
start = Position;
var code_size = body.code_size;
if (code_size < 0 || Length <= (uint) (code_size + Position))
code_size = 0;
var end = start + code_size;
var instructions = body.instructions = new InstructionCollection (method, (code_size + 1) / 2);
while (Position < end) {
var offset = Position - start;
var opcode = ReadOpCode ();
var current = new Instruction (offset, opcode);
if (opcode.OperandType != OperandType.InlineNone)
current.operand = ReadOperand (current);
instructions.Add (current);
}
ResolveBranches (instructions);
}
OpCode ReadOpCode ()
{
var il_opcode = ReadByte ();
return il_opcode != 0xfe
? OpCodes.OneByteOpCode [il_opcode]
: OpCodes.TwoBytesOpCode [ReadByte ()];
}
object ReadOperand (Instruction instruction)
{
switch (instruction.opcode.OperandType) {
case OperandType.InlineSwitch:
var length = ReadInt32 ();
var base_offset = Offset + (4 * length);
var branches = new int [length];
for (int i = 0; i < length; i++)
branches [i] = base_offset + ReadInt32 ();
return branches;
case OperandType.ShortInlineBrTarget:
return ReadSByte () + Offset;
case OperandType.InlineBrTarget:
return ReadInt32 () + Offset;
case OperandType.ShortInlineI:
if (instruction.opcode == OpCodes.Ldc_I4_S)
return ReadSByte ();
return ReadByte ();
case OperandType.InlineI:
return ReadInt32 ();
case OperandType.ShortInlineR:
return ReadSingle ();
case OperandType.InlineR:
return ReadDouble ();
case OperandType.InlineI8:
return ReadInt64 ();
case OperandType.ShortInlineVar:
return GetVariable (ReadByte ());
case OperandType.InlineVar:
return GetVariable (ReadUInt16 ());
case OperandType.ShortInlineArg:
return GetParameter (ReadByte ());
case OperandType.InlineArg:
return GetParameter (ReadUInt16 ());
case OperandType.InlineSig:
return GetCallSite (ReadToken ());
case OperandType.InlineString:
return GetString (ReadToken ());
case OperandType.InlineTok:
case OperandType.InlineType:
case OperandType.InlineMethod:
case OperandType.InlineField:
return reader.LookupToken (ReadToken ());
default:
throw new NotSupportedException ();
}
}
public string GetString (MetadataToken token)
{
return reader.image.UserStringHeap.Read (token.RID);
}
public ParameterDefinition GetParameter (int index)
{
return body.GetParameter (index);
}
public VariableDefinition GetVariable (int index)
{
return body.GetVariable (index);
}
public CallSite GetCallSite (MetadataToken token)
{
return reader.ReadCallSite (token);
}
void ResolveBranches (Collection<Instruction> instructions)
{
var items = instructions.items;
var size = instructions.size;
for (int i = 0; i < size; i++) {
var instruction = items [i];
switch (instruction.opcode.OperandType) {
case OperandType.ShortInlineBrTarget:
case OperandType.InlineBrTarget:
instruction.operand = GetInstruction ((int) instruction.operand);
break;
case OperandType.InlineSwitch:
var offsets = (int []) instruction.operand;
var branches = new Instruction [offsets.Length];
for (int j = 0; j < offsets.Length; j++)
branches [j] = GetInstruction (offsets [j]);
instruction.operand = branches;
break;
}
}
}
Instruction GetInstruction (int offset)
{
return GetInstruction (body.Instructions, offset);
}
static Instruction GetInstruction (Collection<Instruction> instructions, int offset)
{
var size = instructions.size;
var items = instructions.items;
if (offset < 0 || offset > items [size - 1].offset)
return null;
int min = 0;
int max = size - 1;
while (min <= max) {
int mid = min + ((max - min) / 2);
var instruction = items [mid];
var instruction_offset = instruction.offset;
if (offset == instruction_offset)
return instruction;
if (offset < instruction_offset)
max = mid - 1;
else
min = mid + 1;
}
return null;
}
void ReadSection ()
{
Align (4);
const byte fat_format = 0x40;
const byte more_sects = 0x80;
var flags = ReadByte ();
if ((flags & fat_format) == 0)
ReadSmallSection ();
else
ReadFatSection ();
if ((flags & more_sects) != 0)
ReadSection ();
}
void ReadSmallSection ()
{
var count = ReadByte () / 12;
Advance (2);
ReadExceptionHandlers (
count,
() => (int) ReadUInt16 (),
() => (int) ReadByte ());
}
void ReadFatSection ()
{
Advance (-1);
var count = (ReadInt32 () >> 8) / 24;
ReadExceptionHandlers (
count,
ReadInt32,
ReadInt32);
}
// inline ?
void ReadExceptionHandlers (int count, Func<int> read_entry, Func<int> read_length)
{
for (int i = 0; i < count; i++) {
var handler = new ExceptionHandler (
(ExceptionHandlerType) (read_entry () & 0x7));
handler.TryStart = GetInstruction (read_entry ());
handler.TryEnd = GetInstruction (handler.TryStart.Offset + read_length ());
handler.HandlerStart = GetInstruction (read_entry ());
handler.HandlerEnd = GetInstruction (handler.HandlerStart.Offset + read_length ());
ReadExceptionHandlerSpecific (handler);
this.body.ExceptionHandlers.Add (handler);
}
}
void ReadExceptionHandlerSpecific (ExceptionHandler handler)
{
switch (handler.HandlerType) {
case ExceptionHandlerType.Catch:
handler.CatchType = (TypeReference) reader.LookupToken (ReadToken ());
break;
case ExceptionHandlerType.Filter:
handler.FilterStart = GetInstruction (ReadInt32 ());
break;
default:
Advance (4);
break;
}
}
public MetadataToken ReadToken ()
{
return new MetadataToken (ReadUInt32 ());
}
void ReadDebugInfo ()
{
if (method.debug_info.sequence_points != null)
ReadSequencePoints ();
if (method.debug_info.scope != null)
ReadScope (method.debug_info.scope);
if (method.custom_infos != null)
ReadCustomDebugInformations (method);
}
void ReadCustomDebugInformations (MethodDefinition method)
{
var custom_infos = method.custom_infos;
for (int i = 0; i < custom_infos.Count; i++) {
var state_machine_scope = custom_infos [i] as StateMachineScopeDebugInformation;
if (state_machine_scope != null)
ReadStateMachineScope (state_machine_scope);
var async_method = custom_infos [i] as AsyncMethodBodyDebugInformation;
if (async_method != null)
ReadAsyncMethodBody (async_method);
}
}
void ReadAsyncMethodBody (AsyncMethodBodyDebugInformation async_method)
{
if (async_method.catch_handler.Offset > -1)
async_method.catch_handler = new InstructionOffset (GetInstruction (async_method.catch_handler.Offset));
if (!async_method.yields.IsNullOrEmpty ())
for (int i = 0; i < async_method.yields.Count; i++)
async_method.yields [i] = new InstructionOffset (GetInstruction (async_method.yields [i].Offset));
if (!async_method.resumes.IsNullOrEmpty ())
for (int i = 0; i < async_method.resumes.Count; i++)
async_method.resumes [i] = new InstructionOffset (GetInstruction (async_method.resumes [i].Offset));
}
void ReadStateMachineScope (StateMachineScopeDebugInformation state_machine_scope)
{
if (state_machine_scope.scopes.IsNullOrEmpty ())
return;
foreach (var scope in state_machine_scope.scopes) {
scope.start = new InstructionOffset (GetInstruction (scope.start.Offset));
var end_instruction = GetInstruction (scope.end.Offset);
scope.end = end_instruction == null
? new InstructionOffset ()
: new InstructionOffset (end_instruction);
}
}
void ReadSequencePoints ()
{
var symbol = method.debug_info;
for (int i = 0; i < symbol.sequence_points.Count; i++) {
var sequence_point = symbol.sequence_points [i];
var instruction = GetInstruction (sequence_point.Offset);
if (instruction != null)
sequence_point.offset = new InstructionOffset (instruction);
}
}
void ReadScopes (Collection<ScopeDebugInformation> scopes)
{
for (int i = 0; i < scopes.Count; i++)
ReadScope (scopes [i]);
}
void ReadScope (ScopeDebugInformation scope)
{
var start_instruction = GetInstruction (scope.Start.Offset);
if (start_instruction != null)
scope.Start = new InstructionOffset (start_instruction);
var end_instruction = GetInstruction (scope.End.Offset);
scope.End = end_instruction != null
? new InstructionOffset (end_instruction)
: new InstructionOffset ();
if (!scope.variables.IsNullOrEmpty ()) {
for (int i = 0; i < scope.variables.Count; i++) {
var variable_info = scope.variables [i];
var variable = GetVariable (variable_info.Index);
if (variable != null)
variable_info.index = new VariableIndex (variable);
}
}
if (!scope.scopes.IsNullOrEmpty ())
ReadScopes (scope.scopes);
}
#if !READ_ONLY
public ByteBuffer PatchRawMethodBody (MethodDefinition method, CodeWriter writer, out int code_size, out MetadataToken local_var_token)
{
var position = MoveTo (method);
var buffer = new ByteBuffer ();
var flags = ReadByte ();
switch (flags & 0x3) {
case 0x2: // tiny
buffer.WriteByte (flags);
local_var_token = MetadataToken.Zero;
code_size = flags >> 2;
PatchRawCode (buffer, code_size, writer);
break;
case 0x3: // fat
Advance (-1);
PatchRawFatMethod (buffer, writer, out code_size, out local_var_token);
break;
default:
throw new NotSupportedException ();
}
MoveBackTo (position);
return buffer;
}
void PatchRawFatMethod (ByteBuffer buffer, CodeWriter writer, out int code_size, out MetadataToken local_var_token)
{
var flags = ReadUInt16 ();
buffer.WriteUInt16 (flags);
buffer.WriteUInt16 (ReadUInt16 ());
code_size = ReadInt32 ();
buffer.WriteInt32 (code_size);
local_var_token = ReadToken ();
if (local_var_token.RID > 0) {
var variables = ReadVariables (local_var_token);
buffer.WriteUInt32 (variables != null
? writer.GetStandAloneSignature (variables).ToUInt32 ()
: 0);
} else
buffer.WriteUInt32 (0);
PatchRawCode (buffer, code_size, writer);
if ((flags & 0x8) != 0)
PatchRawSection (buffer, writer.metadata);
}
void PatchRawCode (ByteBuffer buffer, int code_size, CodeWriter writer)
{
var metadata = writer.metadata;
buffer.WriteBytes (ReadBytes (code_size));
var end = buffer.position;
buffer.position -= code_size;
while (buffer.position < end) {
OpCode opcode;
var il_opcode = buffer.ReadByte ();
if (il_opcode != 0xfe) {
opcode = OpCodes.OneByteOpCode [il_opcode];
} else {
var il_opcode2 = buffer.ReadByte ();
opcode = OpCodes.TwoBytesOpCode [il_opcode2];
}
switch (opcode.OperandType) {
case OperandType.ShortInlineI:
case OperandType.ShortInlineBrTarget:
case OperandType.ShortInlineVar:
case OperandType.ShortInlineArg:
buffer.position += 1;
break;
case OperandType.InlineVar:
case OperandType.InlineArg:
buffer.position += 2;
break;
case OperandType.InlineBrTarget:
case OperandType.ShortInlineR:
case OperandType.InlineI:
buffer.position += 4;
break;
case OperandType.InlineI8:
case OperandType.InlineR:
buffer.position += 8;
break;
case OperandType.InlineSwitch:
var length = buffer.ReadInt32 ();
buffer.position += length * 4;
break;
case OperandType.InlineString:
var @string = GetString (new MetadataToken (buffer.ReadUInt32 ()));
buffer.position -= 4;
buffer.WriteUInt32 (
new MetadataToken (
TokenType.String,
metadata.user_string_heap.GetStringIndex (@string)).ToUInt32 ());
break;
case OperandType.InlineSig:
var call_site = GetCallSite (new MetadataToken (buffer.ReadUInt32 ()));
buffer.position -= 4;
buffer.WriteUInt32 (writer.GetStandAloneSignature (call_site).ToUInt32 ());
break;
case OperandType.InlineTok:
case OperandType.InlineType:
case OperandType.InlineMethod:
case OperandType.InlineField:
var provider = reader.LookupToken (new MetadataToken (buffer.ReadUInt32 ()));
buffer.position -= 4;
buffer.WriteUInt32 (metadata.LookupToken (provider).ToUInt32 ());
break;
}
}
}
void PatchRawSection (ByteBuffer buffer, MetadataBuilder metadata)
{
var position = Position;
Align (4);
buffer.WriteBytes (Position - position);
const byte fat_format = 0x40;
const byte more_sects = 0x80;
var flags = ReadByte ();
if ((flags & fat_format) == 0) {
buffer.WriteByte (flags);
PatchRawSmallSection (buffer, metadata);
} else
PatchRawFatSection (buffer, metadata);
if ((flags & more_sects) != 0)
PatchRawSection (buffer, metadata);
}
void PatchRawSmallSection (ByteBuffer buffer, MetadataBuilder metadata)
{
var length = ReadByte ();
buffer.WriteByte (length);
Advance (2);
buffer.WriteUInt16 (0);
var count = length / 12;
PatchRawExceptionHandlers (buffer, metadata, count, false);
}
void PatchRawFatSection (ByteBuffer buffer, MetadataBuilder metadata)
{
Advance (-1);
var length = ReadInt32 ();
buffer.WriteInt32 (length);
var count = (length >> 8) / 24;
PatchRawExceptionHandlers (buffer, metadata, count, true);
}
void PatchRawExceptionHandlers (ByteBuffer buffer, MetadataBuilder metadata, int count, bool fat_entry)
{
const int fat_entry_size = 16;
const int small_entry_size = 6;
for (int i = 0; i < count; i++) {
ExceptionHandlerType handler_type;
if (fat_entry) {
var type = ReadUInt32 ();
handler_type = (ExceptionHandlerType) (type & 0x7);
buffer.WriteUInt32 (type);
} else {
var type = ReadUInt16 ();
handler_type = (ExceptionHandlerType) (type & 0x7);
buffer.WriteUInt16 (type);
}
buffer.WriteBytes (ReadBytes (fat_entry ? fat_entry_size : small_entry_size));
switch (handler_type) {
case ExceptionHandlerType.Catch:
var exception = reader.LookupToken (ReadToken ());
buffer.WriteUInt32 (metadata.LookupToken (exception).ToUInt32 ());
break;
default:
buffer.WriteUInt32 (ReadUInt32 ());
break;
}
}
}
#endif
}
}
}
#endregion
#region Mono.Cecil.Cil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Collections.Generic;
using Mono.Collections.Generic;
using Mono.Cecil.Metadata;
using Mono.Cecil.PE;
using RVA = System.UInt32;
#if !READ_ONLY
namespace Mono.Cecil.Cil {
sealed class CodeWriter : ByteBuffer {
readonly RVA code_base;
internal readonly MetadataBuilder metadata;
readonly Dictionary<uint, MetadataToken> standalone_signatures;
readonly Dictionary<ByteBuffer, RVA> tiny_method_bodies;
MethodBody body;
public CodeWriter (MetadataBuilder metadata)
: base (0)
{
this.code_base = metadata.text_map.GetNextRVA (TextSegment.CLIHeader);
this.metadata = metadata;
this.standalone_signatures = new Dictionary<uint, MetadataToken> ();
this.tiny_method_bodies = new Dictionary<ByteBuffer, RVA> (new ByteBufferEqualityComparer ());
}
public RVA WriteMethodBody (MethodDefinition method)
{
RVA rva;
if (IsUnresolved (method)) {
if (method.rva == 0)
return 0;
rva = WriteUnresolvedMethodBody (method);
} else {
if (IsEmptyMethodBody (method.Body))
return 0;
rva = WriteResolvedMethodBody (method);
}
return rva;
}
static bool IsEmptyMethodBody (MethodBody body)
{
return body.instructions.IsNullOrEmpty ()
&& body.variables.IsNullOrEmpty ();
}
static bool IsUnresolved (MethodDefinition method)
{
return method.HasBody && method.HasImage && method.body == null;
}
RVA WriteUnresolvedMethodBody (MethodDefinition method)
{
var code_reader = metadata.module.reader.code;
int code_size;
MetadataToken local_var_token;
var raw_body = code_reader.PatchRawMethodBody (method, this, out code_size, out local_var_token);
var fat_header = (raw_body.buffer [0] & 0x3) == 0x3;
if (fat_header)
Align (4);
var rva = BeginMethod ();
if (fat_header || !GetOrMapTinyMethodBody (raw_body, ref rva)) {
WriteBytes (raw_body);
}
if (method.debug_info == null)
return rva;
var symbol_writer = metadata.symbol_writer;
if (symbol_writer != null) {
method.debug_info.code_size = code_size;
method.debug_info.local_var_token = local_var_token;
symbol_writer.Write (method.debug_info);
}
return rva;
}
RVA WriteResolvedMethodBody(MethodDefinition method)
{
RVA rva;
body = method.Body;
ComputeHeader ();
if (RequiresFatHeader ()) {
Align (4);
rva = BeginMethod ();
WriteFatHeader ();
WriteInstructions ();
if (body.HasExceptionHandlers)
WriteExceptionHandlers ();
} else {
rva = BeginMethod ();
WriteByte ((byte) (0x2 | (body.CodeSize << 2))); // tiny
WriteInstructions ();
var start_position = (int) (rva - code_base);
var body_size = position - start_position;
var body_bytes = new byte [body_size];
Array.Copy (buffer, start_position, body_bytes, 0, body_size);
if (GetOrMapTinyMethodBody (new ByteBuffer (body_bytes), ref rva))
position = start_position;
}
var symbol_writer = metadata.symbol_writer;
if (symbol_writer != null && method.debug_info != null) {
method.debug_info.code_size = body.CodeSize;
method.debug_info.local_var_token = body.local_var_token;
symbol_writer.Write (method.debug_info);
}
return rva;
}
bool GetOrMapTinyMethodBody (ByteBuffer body, ref RVA rva)
{
RVA existing_rva;
if (tiny_method_bodies.TryGetValue (body, out existing_rva)) {
rva = existing_rva;
return true;
}
tiny_method_bodies.Add (body, rva);
return false;
}
void WriteFatHeader ()
{
var body = this.body;
byte flags = 0x3; // fat
if (body.InitLocals)
flags |= 0x10; // init locals
if (body.HasExceptionHandlers)
flags |= 0x8; // more sections
WriteByte (flags);
WriteByte (0x30);
WriteInt16 ((short) body.max_stack_size);
WriteInt32 (body.code_size);
body.local_var_token = body.HasVariables
? GetStandAloneSignature (body.Variables)
: MetadataToken.Zero;
WriteMetadataToken (body.local_var_token);
}
void WriteInstructions ()
{
var instructions = body.Instructions;
var items = instructions.items;
var size = instructions.size;
for (int i = 0; i < size; i++) {
var instruction = items [i];
WriteOpCode (instruction.opcode);
WriteOperand (instruction);
}
}
void WriteOpCode (OpCode opcode)
{
if (opcode.Size == 1) {
WriteByte (opcode.Op2);
} else {
WriteByte (opcode.Op1);
WriteByte (opcode.Op2);
}
}
void WriteOperand (Instruction instruction)
{
var opcode = instruction.opcode;
var operand_type = opcode.OperandType;
if (operand_type == OperandType.InlineNone)
return;
var operand = instruction.operand;
if (operand == null && !(operand_type == OperandType.InlineBrTarget || operand_type == OperandType.ShortInlineBrTarget)) {
throw new ArgumentException ();
}
switch (operand_type) {
case OperandType.InlineSwitch: {
var targets = (Instruction []) operand;
WriteInt32 (targets.Length);
var diff = instruction.Offset + opcode.Size + (4 * (targets.Length + 1));
for (int i = 0; i < targets.Length; i++)
WriteInt32 (GetTargetOffset (targets [i]) - diff);
break;
}
case OperandType.ShortInlineBrTarget: {
var target = (Instruction) operand;
var offset = target != null ? GetTargetOffset (target) : body.code_size;
WriteSByte ((sbyte) (offset - (instruction.Offset + opcode.Size + 1)));
break;
}
case OperandType.InlineBrTarget: {
var target = (Instruction) operand;
var offset = target != null ? GetTargetOffset (target) : body.code_size;
WriteInt32 (offset - (instruction.Offset + opcode.Size + 4));
break;
}
case OperandType.ShortInlineVar:
WriteByte ((byte) GetVariableIndex ((VariableDefinition) operand));
break;
case OperandType.ShortInlineArg:
WriteByte ((byte) GetParameterIndex ((ParameterDefinition) operand));
break;
case OperandType.InlineVar:
WriteInt16 ((short) GetVariableIndex ((VariableDefinition) operand));
break;
case OperandType.InlineArg:
WriteInt16 ((short) GetParameterIndex ((ParameterDefinition) operand));
break;
case OperandType.InlineSig:
WriteMetadataToken (GetStandAloneSignature ((CallSite) operand));
break;
case OperandType.ShortInlineI:
if (opcode == OpCodes.Ldc_I4_S)
WriteSByte ((sbyte) operand);
else
WriteByte ((byte) operand);
break;
case OperandType.InlineI:
WriteInt32 ((int) operand);
break;
case OperandType.InlineI8:
WriteInt64 ((long) operand);
break;
case OperandType.ShortInlineR:
WriteSingle ((float) operand);
break;
case OperandType.InlineR:
WriteDouble ((double) operand);
break;
case OperandType.InlineString:
WriteMetadataToken (
new MetadataToken (
TokenType.String,
GetUserStringIndex ((string) operand)));
break;
case OperandType.InlineType:
case OperandType.InlineField:
case OperandType.InlineMethod:
case OperandType.InlineTok:
WriteMetadataToken (metadata.LookupToken ((IMetadataTokenProvider) operand));
break;
default:
throw new ArgumentException ();
}
}
int GetTargetOffset (Instruction instruction)
{
if (instruction == null) {
var last = body.instructions [body.instructions.size - 1];
return last.offset + last.GetSize ();
}
return instruction.offset;
}
uint GetUserStringIndex (string @string)
{
if (@string == null)
return 0;
return metadata.user_string_heap.GetStringIndex (@string);
}
static int GetVariableIndex (VariableDefinition variable)
{
return variable.Index;
}
int GetParameterIndex (ParameterDefinition parameter)
{
if (body.method.HasThis) {
if (parameter == body.this_parameter)
return 0;
return parameter.Index + 1;
}
return parameter.Index;
}
bool RequiresFatHeader ()
{
var body = this.body;
return body.CodeSize >= 64
|| body.InitLocals
|| body.HasVariables
|| body.HasExceptionHandlers
|| body.MaxStackSize > 8;
}
void ComputeHeader ()
{
int offset = 0;
var instructions = body.instructions;
var items = instructions.items;
var count = instructions.size;
var stack_size = 0;
var max_stack = 0;
Dictionary<Instruction, int> stack_sizes = null;
if (body.HasExceptionHandlers)
ComputeExceptionHandlerStackSize (ref stack_sizes);
for (int i = 0; i < count; i++) {
var instruction = items [i];
instruction.offset = offset;
offset += instruction.GetSize ();
ComputeStackSize (instruction, ref stack_sizes, ref stack_size, ref max_stack);
}
body.code_size = offset;
body.max_stack_size = max_stack;
}
void ComputeExceptionHandlerStackSize (ref Dictionary<Instruction, int> stack_sizes)
{
var exception_handlers = body.ExceptionHandlers;
for (int i = 0; i < exception_handlers.Count; i++) {
var exception_handler = exception_handlers [i];
switch (exception_handler.HandlerType) {
case ExceptionHandlerType.Catch:
AddExceptionStackSize (exception_handler.HandlerStart, ref stack_sizes);
break;
case ExceptionHandlerType.Filter:
AddExceptionStackSize (exception_handler.FilterStart, ref stack_sizes);
AddExceptionStackSize (exception_handler.HandlerStart, ref stack_sizes);
break;
}
}
}
static void AddExceptionStackSize (Instruction handler_start, ref Dictionary<Instruction, int> stack_sizes)
{
if (handler_start == null)
return;
if (stack_sizes == null)
stack_sizes = new Dictionary<Instruction, int> ();
stack_sizes [handler_start] = 1;
}
static void ComputeStackSize (Instruction instruction, ref Dictionary<Instruction, int> stack_sizes, ref int stack_size, ref int max_stack)
{
int computed_size;
if (stack_sizes != null && stack_sizes.TryGetValue (instruction, out computed_size))
stack_size = computed_size;
max_stack = System.Math.Max (max_stack, stack_size);
ComputeStackDelta (instruction, ref stack_size);
max_stack = System.Math.Max (max_stack, stack_size);
CopyBranchStackSize (instruction, ref stack_sizes, stack_size);
ComputeStackSize (instruction, ref stack_size);
}
static void CopyBranchStackSize (Instruction instruction, ref Dictionary<Instruction, int> stack_sizes, int stack_size)
{
if (stack_size == 0)
return;
switch (instruction.opcode.OperandType) {
case OperandType.ShortInlineBrTarget:
case OperandType.InlineBrTarget:
CopyBranchStackSize (ref stack_sizes, (Instruction) instruction.operand, stack_size);
break;
case OperandType.InlineSwitch:
var targets = (Instruction []) instruction.operand;
for (int i = 0; i < targets.Length; i++)
CopyBranchStackSize (ref stack_sizes, targets [i], stack_size);
break;
}
}
static void CopyBranchStackSize (ref Dictionary<Instruction, int> stack_sizes, Instruction target, int stack_size)
{
if (stack_sizes == null)
stack_sizes = new Dictionary<Instruction, int> ();
int branch_stack_size = stack_size;
int computed_size;
if (stack_sizes.TryGetValue (target, out computed_size))
branch_stack_size = System.Math.Max (branch_stack_size, computed_size);
stack_sizes [target] = branch_stack_size;
}
static void ComputeStackSize (Instruction instruction, ref int stack_size)
{
switch (instruction.opcode.FlowControl) {
case FlowControl.Branch:
case FlowControl.Break:
case FlowControl.Throw:
case FlowControl.Return:
stack_size = 0;
break;
}
}
static void ComputeStackDelta (Instruction instruction, ref int stack_size)
{
switch (instruction.opcode.FlowControl) {
case FlowControl.Call: {
var method = (IMethodSignature) instruction.operand;
// pop 'this' argument
if (method.HasImplicitThis() && instruction.opcode.Code != Code.Newobj)
stack_size--;
// pop normal arguments
if (method.HasParameters)
stack_size -= method.Parameters.Count;
// pop function pointer
if (instruction.opcode.Code == Code.Calli)
stack_size--;
// push return value
if (method.ReturnType.etype != ElementType.Void || instruction.opcode.Code == Code.Newobj)
stack_size++;
break;
}
default:
ComputePopDelta (instruction.opcode.StackBehaviourPop, ref stack_size);
ComputePushDelta (instruction.opcode.StackBehaviourPush, ref stack_size);
break;
}
}
static void ComputePopDelta (StackBehaviour pop_behavior, ref int stack_size)
{
switch (pop_behavior) {
case StackBehaviour.Popi:
case StackBehaviour.Popref:
case StackBehaviour.Pop1:
stack_size--;
break;
case StackBehaviour.Pop1_pop1:
case StackBehaviour.Popi_pop1:
case StackBehaviour.Popi_popi:
case StackBehaviour.Popi_popi8:
case StackBehaviour.Popi_popr4:
case StackBehaviour.Popi_popr8:
case StackBehaviour.Popref_pop1:
case StackBehaviour.Popref_popi:
stack_size -= 2;
break;
case StackBehaviour.Popi_popi_popi:
case StackBehaviour.Popref_popi_popi:
case StackBehaviour.Popref_popi_popi8:
case StackBehaviour.Popref_popi_popr4:
case StackBehaviour.Popref_popi_popr8:
case StackBehaviour.Popref_popi_popref:
stack_size -= 3;
break;
case StackBehaviour.PopAll:
stack_size = 0;
break;
}
}
static void ComputePushDelta (StackBehaviour push_behaviour, ref int stack_size)
{
switch (push_behaviour) {
case StackBehaviour.Push1:
case StackBehaviour.Pushi:
case StackBehaviour.Pushi8:
case StackBehaviour.Pushr4:
case StackBehaviour.Pushr8:
case StackBehaviour.Pushref:
stack_size++;
break;
case StackBehaviour.Push1_push1:
stack_size += 2;
break;
}
}
void WriteExceptionHandlers ()
{
Align (4);
var handlers = body.ExceptionHandlers;
if (handlers.Count < 0x15 && !RequiresFatSection (handlers))
WriteSmallSection (handlers);
else
WriteFatSection (handlers);
}
static bool RequiresFatSection (Collection<ExceptionHandler> handlers)
{
for (int i = 0; i < handlers.Count; i++) {
var handler = handlers [i];
if (IsFatRange (handler.TryStart, handler.TryEnd))
return true;
if (IsFatRange (handler.HandlerStart, handler.HandlerEnd))
return true;
if (handler.HandlerType == ExceptionHandlerType.Filter
&& IsFatRange (handler.FilterStart, handler.HandlerStart))
return true;
}
return false;
}
static bool IsFatRange (Instruction start, Instruction end)
{
if (start == null)
throw new ArgumentException ();
if (end == null)
return true;
return end.Offset - start.Offset > 255 || start.Offset > 65535;
}
void WriteSmallSection (Collection<ExceptionHandler> handlers)
{
const byte eh_table = 0x1;
WriteByte (eh_table);
WriteByte ((byte) (handlers.Count * 12 + 4));
WriteBytes (2);
WriteExceptionHandlers (
handlers,
i => WriteUInt16 ((ushort) i),
i => WriteByte ((byte) i));
}
void WriteFatSection (Collection<ExceptionHandler> handlers)
{
const byte eh_table = 0x1;
const byte fat_format = 0x40;
WriteByte (eh_table | fat_format);
int size = handlers.Count * 24 + 4;
WriteByte ((byte) (size & 0xff));
WriteByte ((byte) ((size >> 8) & 0xff));
WriteByte ((byte) ((size >> 16) & 0xff));
WriteExceptionHandlers (handlers, WriteInt32, WriteInt32);
}
void WriteExceptionHandlers (Collection<ExceptionHandler> handlers, Action<int> write_entry, Action<int> write_length)
{
for (int i = 0; i < handlers.Count; i++) {
var handler = handlers [i];
write_entry ((int) handler.HandlerType);
write_entry (handler.TryStart.Offset);
write_length (GetTargetOffset (handler.TryEnd) - handler.TryStart.Offset);
write_entry (handler.HandlerStart.Offset);
write_length (GetTargetOffset (handler.HandlerEnd) - handler.HandlerStart.Offset);
WriteExceptionHandlerSpecific (handler);
}
}
void WriteExceptionHandlerSpecific (ExceptionHandler handler)
{
switch (handler.HandlerType) {
case ExceptionHandlerType.Catch:
WriteMetadataToken (metadata.LookupToken (handler.CatchType));
break;
case ExceptionHandlerType.Filter:
WriteInt32 (handler.FilterStart.Offset);
break;
default:
WriteInt32 (0);
break;
}
}
public MetadataToken GetStandAloneSignature (Collection<VariableDefinition> variables)
{
var signature = metadata.GetLocalVariableBlobIndex (variables);
return GetStandAloneSignatureToken (signature);
}
public MetadataToken GetStandAloneSignature (CallSite call_site)
{
var signature = metadata.GetCallSiteBlobIndex (call_site);
var token = GetStandAloneSignatureToken (signature);
call_site.MetadataToken = token;
return token;
}
MetadataToken GetStandAloneSignatureToken (uint signature)
{
MetadataToken token;
if (standalone_signatures.TryGetValue (signature, out token))
return token;
token = new MetadataToken (TokenType.Signature, metadata.AddStandAloneSignature (signature));
standalone_signatures.Add (signature, token);
return token;
}
RVA BeginMethod ()
{
return (RVA)(code_base + position);
}
void WriteMetadataToken (MetadataToken token)
{
WriteUInt32 (token.ToUInt32 ());
}
void Align (int align)
{
align--;
WriteBytes (((position + align) & ~align) - position);
}
}
}
#endif
}
#endregion
#region Mono.Cecil.Cil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil.Cil {
internal enum DocumentType {
Other,
Text,
}
internal enum DocumentHashAlgorithm {
None,
MD5,
SHA1,
SHA256,
}
internal enum DocumentLanguage {
Other,
C,
Cpp,
CSharp,
Basic,
Java,
Cobol,
Pascal,
Cil,
JScript,
Smc,
MCpp,
FSharp,
}
internal enum DocumentLanguageVendor {
Other,
Microsoft,
}
internal sealed class Document : DebugInformation {
string url;
Guid type;
Guid hash_algorithm;
Guid language;
Guid language_vendor;
byte [] hash;
byte [] embedded_source;
public string Url {
get { return url; }
set { url = value; }
}
public DocumentType Type {
get { return type.ToType (); }
set { type = value.ToGuid (); }
}
public Guid TypeGuid {
get { return type; }
set { type = value; }
}
public DocumentHashAlgorithm HashAlgorithm {
get { return hash_algorithm.ToHashAlgorithm (); }
set { hash_algorithm = value.ToGuid (); }
}
public Guid HashAlgorithmGuid {
get { return hash_algorithm; }
set { hash_algorithm = value; }
}
public DocumentLanguage Language {
get { return language.ToLanguage (); }
set { language = value.ToGuid (); }
}
public Guid LanguageGuid {
get { return language; }
set { language = value; }
}
public DocumentLanguageVendor LanguageVendor {
get { return language_vendor.ToVendor (); }
set { language_vendor = value.ToGuid (); }
}
public Guid LanguageVendorGuid {
get { return language_vendor; }
set { language_vendor = value; }
}
public byte [] Hash {
get { return hash; }
set { hash = value; }
}
public byte[] EmbeddedSource {
get { return embedded_source; }
set { embedded_source = value; }
}
public Document (string url)
{
this.url = url;
this.hash = Empty<byte>.Array;
this.embedded_source = Empty<byte>.Array;
this.token = new MetadataToken (TokenType.Document);
}
}
}
}
#endregion
#region Mono.Cecil.Cil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil.Cil {
internal enum ExceptionHandlerType {
Catch = 0,
Filter = 1,
Finally = 2,
Fault = 4,
}
internal sealed class ExceptionHandler {
Instruction try_start;
Instruction try_end;
Instruction filter_start;
Instruction handler_start;
Instruction handler_end;
TypeReference catch_type;
ExceptionHandlerType handler_type;
public Instruction TryStart {
get { return try_start; }
set { try_start = value; }
}
public Instruction TryEnd {
get { return try_end; }
set { try_end = value; }
}
public Instruction FilterStart {
get { return filter_start; }
set { filter_start = value; }
}
public Instruction HandlerStart {
get { return handler_start; }
set { handler_start = value; }
}
public Instruction HandlerEnd {
get { return handler_end; }
set { handler_end = value; }
}
public TypeReference CatchType {
get { return catch_type; }
set { catch_type = value; }
}
public ExceptionHandlerType HandlerType {
get { return handler_type; }
set { handler_type = value; }
}
public ExceptionHandler (ExceptionHandlerType handlerType)
{
this.handler_type = handlerType;
}
}
}
}
#endregion
#region Mono.Cecil.Cil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Collections.Generic;
namespace Mono.Cecil.Cil {
internal sealed class ILProcessor {
readonly MethodBody body;
readonly Collection<Instruction> instructions;
public MethodBody Body {
get { return body; }
}
internal ILProcessor (MethodBody body)
{
this.body = body;
this.instructions = body.Instructions;
}
public Instruction Create (OpCode opcode)
{
return Instruction.Create (opcode);
}
public Instruction Create (OpCode opcode, TypeReference type)
{
return Instruction.Create (opcode, type);
}
public Instruction Create (OpCode opcode, CallSite site)
{
return Instruction.Create (opcode, site);
}
public Instruction Create (OpCode opcode, MethodReference method)
{
return Instruction.Create (opcode, method);
}
public Instruction Create (OpCode opcode, FieldReference field)
{
return Instruction.Create (opcode, field);
}
public Instruction Create (OpCode opcode, string value)
{
return Instruction.Create (opcode, value);
}
public Instruction Create (OpCode opcode, sbyte value)
{
return Instruction.Create (opcode, value);
}
public Instruction Create (OpCode opcode, byte value)
{
if (opcode.OperandType == OperandType.ShortInlineVar)
return Instruction.Create (opcode, body.Variables [value]);
if (opcode.OperandType == OperandType.ShortInlineArg)
return Instruction.Create (opcode, body.GetParameter (value));
return Instruction.Create (opcode, value);
}
public Instruction Create (OpCode opcode, int value)
{
if (opcode.OperandType == OperandType.InlineVar)
return Instruction.Create (opcode, body.Variables [value]);
if (opcode.OperandType == OperandType.InlineArg)
return Instruction.Create (opcode, body.GetParameter (value));
return Instruction.Create (opcode, value);
}
public Instruction Create (OpCode opcode, long value)
{
return Instruction.Create (opcode, value);
}
public Instruction Create (OpCode opcode, float value)
{
return Instruction.Create (opcode, value);
}
public Instruction Create (OpCode opcode, double value)
{
return Instruction.Create (opcode, value);
}
public Instruction Create (OpCode opcode, Instruction target)
{
return Instruction.Create (opcode, target);
}
public Instruction Create (OpCode opcode, Instruction [] targets)
{
return Instruction.Create (opcode, targets);
}
public Instruction Create (OpCode opcode, VariableDefinition variable)
{
return Instruction.Create (opcode, variable);
}
public Instruction Create (OpCode opcode, ParameterDefinition parameter)
{
return Instruction.Create (opcode, parameter);
}
public void Emit (OpCode opcode)
{
Append (Create (opcode));
}
public void Emit (OpCode opcode, TypeReference type)
{
Append (Create (opcode, type));
}
public void Emit (OpCode opcode, MethodReference method)
{
Append (Create (opcode, method));
}
public void Emit (OpCode opcode, CallSite site)
{
Append (Create (opcode, site));
}
public void Emit (OpCode opcode, FieldReference field)
{
Append (Create (opcode, field));
}
public void Emit (OpCode opcode, string value)
{
Append (Create (opcode, value));
}
public void Emit (OpCode opcode, byte value)
{
Append (Create (opcode, value));
}
public void Emit (OpCode opcode, sbyte value)
{
Append (Create (opcode, value));
}
public void Emit (OpCode opcode, int value)
{
Append (Create (opcode, value));
}
public void Emit (OpCode opcode, long value)
{
Append (Create (opcode, value));
}
public void Emit (OpCode opcode, float value)
{
Append (Create (opcode, value));
}
public void Emit (OpCode opcode, double value)
{
Append (Create (opcode, value));
}
public void Emit (OpCode opcode, Instruction target)
{
Append (Create (opcode, target));
}
public void Emit (OpCode opcode, Instruction [] targets)
{
Append (Create (opcode, targets));
}
public void Emit (OpCode opcode, VariableDefinition variable)
{
Append (Create (opcode, variable));
}
public void Emit (OpCode opcode, ParameterDefinition parameter)
{
Append (Create (opcode, parameter));
}
public void InsertBefore (Instruction target, Instruction instruction)
{
if (target == null)
throw new ArgumentNullException ("target");
if (instruction == null)
throw new ArgumentNullException ("instruction");
var index = instructions.IndexOf (target);
if (index == -1)
throw new ArgumentOutOfRangeException ("target");
instructions.Insert (index, instruction);
}
public void InsertAfter (Instruction target, Instruction instruction)
{
if (target == null)
throw new ArgumentNullException ("target");
if (instruction == null)
throw new ArgumentNullException ("instruction");
var index = instructions.IndexOf (target);
if (index == -1)
throw new ArgumentOutOfRangeException ("target");
instructions.Insert (index + 1, instruction);
}
public void Append (Instruction instruction)
{
if (instruction == null)
throw new ArgumentNullException ("instruction");
instructions.Add (instruction);
}
public void Replace (Instruction target, Instruction instruction)
{
if (target == null)
throw new ArgumentNullException ("target");
if (instruction == null)
throw new ArgumentNullException ("instruction");
InsertAfter (target, instruction);
Remove (target);
}
public void Remove (Instruction instruction)
{
if (instruction == null)
throw new ArgumentNullException ("instruction");
if (!instructions.Remove (instruction))
throw new ArgumentOutOfRangeException ("instruction");
}
}
}
}
#endregion
#region Mono.Cecil.Cil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Text;
namespace Mono.Cecil.Cil {
internal sealed class Instruction {
internal int offset;
internal OpCode opcode;
internal object operand;
internal Instruction previous;
internal Instruction next;
public int Offset {
get { return offset; }
set { offset = value; }
}
public OpCode OpCode {
get { return opcode; }
set { opcode = value; }
}
public object Operand {
get { return operand; }
set { operand = value; }
}
public Instruction Previous {
get { return previous; }
set { previous = value; }
}
public Instruction Next {
get { return next; }
set { next = value; }
}
internal Instruction (int offset, OpCode opCode)
{
this.offset = offset;
this.opcode = opCode;
}
internal Instruction (OpCode opcode, object operand)
{
this.opcode = opcode;
this.operand = operand;
}
public int GetSize ()
{
int size = opcode.Size;
switch (opcode.OperandType) {
case OperandType.InlineSwitch:
return size + (1 + ((Instruction []) operand).Length) * 4;
case OperandType.InlineI8:
case OperandType.InlineR:
return size + 8;
case OperandType.InlineBrTarget:
case OperandType.InlineField:
case OperandType.InlineI:
case OperandType.InlineMethod:
case OperandType.InlineString:
case OperandType.InlineTok:
case OperandType.InlineType:
case OperandType.ShortInlineR:
case OperandType.InlineSig:
return size + 4;
case OperandType.InlineArg:
case OperandType.InlineVar:
return size + 2;
case OperandType.ShortInlineBrTarget:
case OperandType.ShortInlineI:
case OperandType.ShortInlineArg:
case OperandType.ShortInlineVar:
return size + 1;
default:
return size;
}
}
public override string ToString ()
{
var instruction = new StringBuilder ();
AppendLabel (instruction, this);
instruction.Append (':');
instruction.Append (' ');
instruction.Append (opcode.Name);
if (operand == null)
return instruction.ToString ();
instruction.Append (' ');
switch (opcode.OperandType) {
case OperandType.ShortInlineBrTarget:
case OperandType.InlineBrTarget:
AppendLabel (instruction, (Instruction) operand);
break;
case OperandType.InlineSwitch:
var labels = (Instruction []) operand;
for (int i = 0; i < labels.Length; i++) {
if (i > 0)
instruction.Append (',');
AppendLabel (instruction, labels [i]);
}
break;
case OperandType.InlineString:
instruction.Append ('\"');
instruction.Append (operand);
instruction.Append ('\"');
break;
default:
instruction.Append (operand);
break;
}
return instruction.ToString ();
}
static void AppendLabel (StringBuilder builder, Instruction instruction)
{
builder.Append ("IL_");
builder.Append (instruction.offset.ToString ("x4"));
}
public static Instruction Create (OpCode opcode)
{
if (opcode.OperandType != OperandType.InlineNone)
throw new ArgumentException ("opcode");
return new Instruction (opcode, null);
}
public static Instruction Create (OpCode opcode, TypeReference type)
{
if (type == null)
throw new ArgumentNullException ("type");
if (opcode.OperandType != OperandType.InlineType &&
opcode.OperandType != OperandType.InlineTok)
throw new ArgumentException ("opcode");
return new Instruction (opcode, type);
}
public static Instruction Create (OpCode opcode, CallSite site)
{
if (site == null)
throw new ArgumentNullException ("site");
if (opcode.Code != Code.Calli)
throw new ArgumentException ("code");
return new Instruction (opcode, site);
}
public static Instruction Create (OpCode opcode, MethodReference method)
{
if (method == null)
throw new ArgumentNullException ("method");
if (opcode.OperandType != OperandType.InlineMethod &&
opcode.OperandType != OperandType.InlineTok)
throw new ArgumentException ("opcode");
return new Instruction (opcode, method);
}
public static Instruction Create (OpCode opcode, FieldReference field)
{
if (field == null)
throw new ArgumentNullException ("field");
if (opcode.OperandType != OperandType.InlineField &&
opcode.OperandType != OperandType.InlineTok)
throw new ArgumentException ("opcode");
return new Instruction (opcode, field);
}
public static Instruction Create (OpCode opcode, string value)
{
if (value == null)
throw new ArgumentNullException ("value");
if (opcode.OperandType != OperandType.InlineString)
throw new ArgumentException ("opcode");
return new Instruction (opcode, value);
}
public static Instruction Create (OpCode opcode, sbyte value)
{
if (opcode.OperandType != OperandType.ShortInlineI &&
opcode != OpCodes.Ldc_I4_S)
throw new ArgumentException ("opcode");
return new Instruction (opcode, value);
}
public static Instruction Create (OpCode opcode, byte value)
{
if (opcode.OperandType != OperandType.ShortInlineI ||
opcode == OpCodes.Ldc_I4_S)
throw new ArgumentException ("opcode");
return new Instruction (opcode, value);
}
public static Instruction Create (OpCode opcode, int value)
{
if (opcode.OperandType != OperandType.InlineI)
throw new ArgumentException ("opcode");
return new Instruction (opcode, value);
}
public static Instruction Create (OpCode opcode, long value)
{
if (opcode.OperandType != OperandType.InlineI8)
throw new ArgumentException ("opcode");
return new Instruction (opcode, value);
}
public static Instruction Create (OpCode opcode, float value)
{
if (opcode.OperandType != OperandType.ShortInlineR)
throw new ArgumentException ("opcode");
return new Instruction (opcode, value);
}
public static Instruction Create (OpCode opcode, double value)
{
if (opcode.OperandType != OperandType.InlineR)
throw new ArgumentException ("opcode");
return new Instruction (opcode, value);
}
public static Instruction Create (OpCode opcode, Instruction target)
{
if (target == null)
throw new ArgumentNullException ("target");
if (opcode.OperandType != OperandType.InlineBrTarget &&
opcode.OperandType != OperandType.ShortInlineBrTarget)
throw new ArgumentException ("opcode");
return new Instruction (opcode, target);
}
public static Instruction Create (OpCode opcode, Instruction [] targets)
{
if (targets == null)
throw new ArgumentNullException ("targets");
if (opcode.OperandType != OperandType.InlineSwitch)
throw new ArgumentException ("opcode");
return new Instruction (opcode, targets);
}
public static Instruction Create (OpCode opcode, VariableDefinition variable)
{
if (variable == null)
throw new ArgumentNullException ("variable");
if (opcode.OperandType != OperandType.ShortInlineVar &&
opcode.OperandType != OperandType.InlineVar)
throw new ArgumentException ("opcode");
return new Instruction (opcode, variable);
}
public static Instruction Create (OpCode opcode, ParameterDefinition parameter)
{
if (parameter == null)
throw new ArgumentNullException ("parameter");
if (opcode.OperandType != OperandType.ShortInlineArg &&
opcode.OperandType != OperandType.InlineArg)
throw new ArgumentException ("opcode");
return new Instruction (opcode, parameter);
}
}
}
}
#endregion
#region Mono.Cecil.Cil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Threading;
using Mono.Collections.Generic;
namespace Mono.Cecil.Cil {
internal sealed class MethodBody {
readonly internal MethodDefinition method;
internal ParameterDefinition this_parameter;
internal int max_stack_size;
internal int code_size;
internal bool init_locals;
internal MetadataToken local_var_token;
internal Collection<Instruction> instructions;
internal Collection<ExceptionHandler> exceptions;
internal Collection<VariableDefinition> variables;
public MethodDefinition Method {
get { return method; }
}
public int MaxStackSize {
get { return max_stack_size; }
set { max_stack_size = value; }
}
public int CodeSize {
get { return code_size; }
}
public bool InitLocals {
get { return init_locals; }
set { init_locals = value; }
}
public MetadataToken LocalVarToken {
get { return local_var_token; }
set { local_var_token = value; }
}
public Collection<Instruction> Instructions {
get { return instructions ?? (instructions = new InstructionCollection (method)); }
}
public bool HasExceptionHandlers {
get { return !exceptions.IsNullOrEmpty (); }
}
public Collection<ExceptionHandler> ExceptionHandlers {
get { return exceptions ?? (exceptions = new Collection<ExceptionHandler> ()); }
}
public bool HasVariables {
get { return !variables.IsNullOrEmpty (); }
}
public Collection<VariableDefinition> Variables {
get { return variables ?? (variables = new VariableDefinitionCollection ()); }
}
public ParameterDefinition ThisParameter {
get {
if (method == null || method.DeclaringType == null)
throw new NotSupportedException ();
if (!method.HasThis)
return null;
if (this_parameter == null)
Interlocked.CompareExchange (ref this_parameter, CreateThisParameter (method), null);
return this_parameter;
}
}
static ParameterDefinition CreateThisParameter (MethodDefinition method)
{
var parameter_type = method.DeclaringType as TypeReference;
if (parameter_type.HasGenericParameters) {
var instance = new GenericInstanceType (parameter_type);
for (int i = 0; i < parameter_type.GenericParameters.Count; i++)
instance.GenericArguments.Add (parameter_type.GenericParameters [i]);
parameter_type = instance;
}
if (parameter_type.IsValueType || parameter_type.IsPrimitive)
parameter_type = new ByReferenceType (parameter_type);
return new ParameterDefinition (parameter_type, method);
}
public MethodBody (MethodDefinition method)
{
this.method = method;
}
public ILProcessor GetILProcessor ()
{
return new ILProcessor (this);
}
}
sealed class VariableDefinitionCollection : Collection<VariableDefinition> {
internal VariableDefinitionCollection ()
{
}
internal VariableDefinitionCollection (int capacity)
: base (capacity)
{
}
protected override void OnAdd (VariableDefinition item, int index)
{
item.index = index;
}
protected override void OnInsert (VariableDefinition item, int index)
{
item.index = index;
for (int i = index; i < size; i++)
items [i].index = i + 1;
}
protected override void OnSet (VariableDefinition item, int index)
{
item.index = index;
}
protected override void OnRemove (VariableDefinition item, int index)
{
item.index = -1;
for (int i = index + 1; i < size; i++)
items [i].index = i - 1;
}
}
class InstructionCollection : Collection<Instruction> {
readonly MethodDefinition method;
internal InstructionCollection (MethodDefinition method)
{
this.method = method;
}
internal InstructionCollection (MethodDefinition method, int capacity)
: base (capacity)
{
this.method = method;
}
protected override void OnAdd (Instruction item, int index)
{
if (index == 0)
return;
var previous = items [index - 1];
previous.next = item;
item.previous = previous;
}
protected override void OnInsert (Instruction item, int index)
{
if (size == 0)
return;
var current = items [index];
if (current == null) {
var last = items [index - 1];
last.next = item;
item.previous = last;
return;
}
var previous = current.previous;
if (previous != null) {
previous.next = item;
item.previous = previous;
}
current.previous = item;
item.next = current;
}
protected override void OnSet (Instruction item, int index)
{
var current = items [index];
item.previous = current.previous;
item.next = current.next;
current.previous = null;
current.next = null;
}
protected override void OnRemove (Instruction item, int index)
{
var previous = item.previous;
if (previous != null)
previous.next = item.next;
var next = item.next;
if (next != null)
next.previous = item.previous;
RemoveSequencePoint (item);
item.previous = null;
item.next = null;
}
void RemoveSequencePoint (Instruction instruction)
{
var debug_info = method.debug_info;
if (debug_info == null || !debug_info.HasSequencePoints)
return;
var sequence_points = debug_info.sequence_points;
for (int i = 0; i < sequence_points.Count; i++) {
if (sequence_points [i].Offset == instruction.offset) {
sequence_points.RemoveAt (i);
return;
}
}
}
}
}
}
#endregion
#region Mono.Cecil.Cil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil.Cil {
internal enum FlowControl {
Branch,
Break,
Call,
Cond_Branch,
Meta,
Next,
Phi,
Return,
Throw,
}
internal enum OpCodeType {
Annotation,
Macro,
Nternal,
Objmodel,
Prefix,
Primitive,
}
internal enum OperandType {
InlineBrTarget,
InlineField,
InlineI,
InlineI8,
InlineMethod,
InlineNone,
InlinePhi,
InlineR,
InlineSig,
InlineString,
InlineSwitch,
InlineTok,
InlineType,
InlineVar,
InlineArg,
ShortInlineBrTarget,
ShortInlineI,
ShortInlineR,
ShortInlineVar,
ShortInlineArg,
}
internal enum StackBehaviour {
Pop0,
Pop1,
Pop1_pop1,
Popi,
Popi_pop1,
Popi_popi,
Popi_popi8,
Popi_popi_popi,
Popi_popr4,
Popi_popr8,
Popref,
Popref_pop1,
Popref_popi,
Popref_popi_popi,
Popref_popi_popi8,
Popref_popi_popr4,
Popref_popi_popr8,
Popref_popi_popref,
PopAll,
Push0,
Push1,
Push1_push1,
Pushi,
Pushi8,
Pushr4,
Pushr8,
Pushref,
Varpop,
Varpush,
}
internal struct OpCode : IEquatable<OpCode> {
readonly byte op1;
readonly byte op2;
readonly byte code;
readonly byte flow_control;
readonly byte opcode_type;
readonly byte operand_type;
readonly byte stack_behavior_pop;
readonly byte stack_behavior_push;
public string Name {
get { return OpCodeNames.names [(int) Code]; }
}
public int Size {
get { return op1 == 0xff ? 1 : 2; }
}
public byte Op1 {
get { return op1; }
}
public byte Op2 {
get { return op2; }
}
public short Value {
get { return op1 == 0xff ? op2 : (short) ((op1 << 8) | op2); }
}
public Code Code {
get { return (Code) code; }
}
public FlowControl FlowControl {
get { return (FlowControl) flow_control; }
}
public OpCodeType OpCodeType {
get { return (OpCodeType) opcode_type; }
}
public OperandType OperandType {
get { return (OperandType) operand_type; }
}
public StackBehaviour StackBehaviourPop {
get { return (StackBehaviour) stack_behavior_pop; }
}
public StackBehaviour StackBehaviourPush {
get { return (StackBehaviour) stack_behavior_push; }
}
internal OpCode (int x, int y)
{
this.op1 = (byte) ((x >> 0) & 0xff);
this.op2 = (byte) ((x >> 8) & 0xff);
this.code = (byte) ((x >> 16) & 0xff);
this.flow_control = (byte) ((x >> 24) & 0xff);
this.opcode_type = (byte) ((y >> 0) & 0xff);
this.operand_type = (byte) ((y >> 8) & 0xff);
this.stack_behavior_pop = (byte) ((y >> 16) & 0xff);
this.stack_behavior_push = (byte) ((y >> 24) & 0xff);
if (op1 == 0xff)
OpCodes.OneByteOpCode [op2] = this;
else
OpCodes.TwoBytesOpCode [op2] = this;
}
public override int GetHashCode ()
{
return Value;
}
public override bool Equals (object obj)
{
if (!(obj is OpCode))
return false;
var opcode = (OpCode) obj;
return op1 == opcode.op1 && op2 == opcode.op2;
}
public bool Equals (OpCode opcode)
{
return op1 == opcode.op1 && op2 == opcode.op2;
}
public static bool operator == (OpCode one, OpCode other)
{
return one.op1 == other.op1 && one.op2 == other.op2;
}
public static bool operator != (OpCode one, OpCode other)
{
return one.op1 != other.op1 || one.op2 != other.op2;
}
public override string ToString ()
{
return Name;
}
}
static class OpCodeNames {
internal static readonly string [] names;
static OpCodeNames ()
{
var table = new byte [] {
3, 110, 111, 112,
5, 98, 114, 101, 97, 107,
7, 108, 100, 97, 114, 103, 46, 48,
7, 108, 100, 97, 114, 103, 46, 49,
7, 108, 100, 97, 114, 103, 46, 50,
7, 108, 100, 97, 114, 103, 46, 51,
7, 108, 100, 108, 111, 99, 46, 48,
7, 108, 100, 108, 111, 99, 46, 49,
7, 108, 100, 108, 111, 99, 46, 50,
7, 108, 100, 108, 111, 99, 46, 51,
7, 115, 116, 108, 111, 99, 46, 48,
7, 115, 116, 108, 111, 99, 46, 49,
7, 115, 116, 108, 111, 99, 46, 50,
7, 115, 116, 108, 111, 99, 46, 51,
7, 108, 100, 97, 114, 103, 46, 115,
8, 108, 100, 97, 114, 103, 97, 46, 115,
7, 115, 116, 97, 114, 103, 46, 115,
7, 108, 100, 108, 111, 99, 46, 115,
8, 108, 100, 108, 111, 99, 97, 46, 115,
7, 115, 116, 108, 111, 99, 46, 115,
6, 108, 100, 110, 117, 108, 108,
9, 108, 100, 99, 46, 105, 52, 46, 109, 49,
8, 108, 100, 99, 46, 105, 52, 46, 48,
8, 108, 100, 99, 46, 105, 52, 46, 49,
8, 108, 100, 99, 46, 105, 52, 46, 50,
8, 108, 100, 99, 46, 105, 52, 46, 51,
8, 108, 100, 99, 46, 105, 52, 46, 52,
8, 108, 100, 99, 46, 105, 52, 46, 53,
8, 108, 100, 99, 46, 105, 52, 46, 54,
8, 108, 100, 99, 46, 105, 52, 46, 55,
8, 108, 100, 99, 46, 105, 52, 46, 56,
8, 108, 100, 99, 46, 105, 52, 46, 115,
6, 108, 100, 99, 46, 105, 52,
6, 108, 100, 99, 46, 105, 56,
6, 108, 100, 99, 46, 114, 52,
6, 108, 100, 99, 46, 114, 56,
3, 100, 117, 112,
3, 112, 111, 112,
3, 106, 109, 112,
4, 99, 97, 108, 108,
5, 99, 97, 108, 108, 105,
3, 114, 101, 116,
4, 98, 114, 46, 115,
9, 98, 114, 102, 97, 108, 115, 101, 46, 115,
8, 98, 114, 116, 114, 117, 101, 46, 115,
5, 98, 101, 113, 46, 115,
5, 98, 103, 101, 46, 115,
5, 98, 103, 116, 46, 115,
5, 98, 108, 101, 46, 115,
5, 98, 108, 116, 46, 115,
8, 98, 110, 101, 46, 117, 110, 46, 115,
8, 98, 103, 101, 46, 117, 110, 46, 115,
8, 98, 103, 116, 46, 117, 110, 46, 115,
8, 98, 108, 101, 46, 117, 110, 46, 115,
8, 98, 108, 116, 46, 117, 110, 46, 115,
2, 98, 114,
7, 98, 114, 102, 97, 108, 115, 101,
6, 98, 114, 116, 114, 117, 101,
3, 98, 101, 113,
3, 98, 103, 101,
3, 98, 103, 116,
3, 98, 108, 101,
3, 98, 108, 116,
6, 98, 110, 101, 46, 117, 110,
6, 98, 103, 101, 46, 117, 110,
6, 98, 103, 116, 46, 117, 110,
6, 98, 108, 101, 46, 117, 110,
6, 98, 108, 116, 46, 117, 110,
6, 115, 119, 105, 116, 99, 104,
8, 108, 100, 105, 110, 100, 46, 105, 49,
8, 108, 100, 105, 110, 100, 46, 117, 49,
8, 108, 100, 105, 110, 100, 46, 105, 50,
8, 108, 100, 105, 110, 100, 46, 117, 50,
8, 108, 100, 105, 110, 100, 46, 105, 52,
8, 108, 100, 105, 110, 100, 46, 117, 52,
8, 108, 100, 105, 110, 100, 46, 105, 56,
7, 108, 100, 105, 110, 100, 46, 105,
8, 108, 100, 105, 110, 100, 46, 114, 52,
8, 108, 100, 105, 110, 100, 46, 114, 56,
9, 108, 100, 105, 110, 100, 46, 114, 101, 102,
9, 115, 116, 105, 110, 100, 46, 114, 101, 102,
8, 115, 116, 105, 110, 100, 46, 105, 49,
8, 115, 116, 105, 110, 100, 46, 105, 50,
8, 115, 116, 105, 110, 100, 46, 105, 52,
8, 115, 116, 105, 110, 100, 46, 105, 56,
8, 115, 116, 105, 110, 100, 46, 114, 52,
8, 115, 116, 105, 110, 100, 46, 114, 56,
3, 97, 100, 100,
3, 115, 117, 98,
3, 109, 117, 108,
3, 100, 105, 118,
6, 100, 105, 118, 46, 117, 110,
3, 114, 101, 109,
6, 114, 101, 109, 46, 117, 110,
3, 97, 110, 100,
2, 111, 114,
3, 120, 111, 114,
3, 115, 104, 108,
3, 115, 104, 114,
6, 115, 104, 114, 46, 117, 110,
3, 110, 101, 103,
3, 110, 111, 116,
7, 99, 111, 110, 118, 46, 105, 49,
7, 99, 111, 110, 118, 46, 105, 50,
7, 99, 111, 110, 118, 46, 105, 52,
7, 99, 111, 110, 118, 46, 105, 56,
7, 99, 111, 110, 118, 46, 114, 52,
7, 99, 111, 110, 118, 46, 114, 56,
7, 99, 111, 110, 118, 46, 117, 52,
7, 99, 111, 110, 118, 46, 117, 56,
8, 99, 97, 108, 108, 118, 105, 114, 116,
5, 99, 112, 111, 98, 106,
5, 108, 100, 111, 98, 106,
5, 108, 100, 115, 116, 114,
6, 110, 101, 119, 111, 98, 106,
9, 99, 97, 115, 116, 99, 108, 97, 115, 115,
6, 105, 115, 105, 110, 115, 116,
9, 99, 111, 110, 118, 46, 114, 46, 117, 110,
5, 117, 110, 98, 111, 120,
5, 116, 104, 114, 111, 119,
5, 108, 100, 102, 108, 100,
6, 108, 100, 102, 108, 100, 97,
5, 115, 116, 102, 108, 100,
6, 108, 100, 115, 102, 108, 100,
7, 108, 100, 115, 102, 108, 100, 97,
6, 115, 116, 115, 102, 108, 100,
5, 115, 116, 111, 98, 106,
14, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 49, 46, 117, 110,
14, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 50, 46, 117, 110,
14, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 52, 46, 117, 110,
14, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 56, 46, 117, 110,
14, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 49, 46, 117, 110,
14, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 50, 46, 117, 110,
14, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 52, 46, 117, 110,
14, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 56, 46, 117, 110,
13, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 46, 117, 110,
13, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 46, 117, 110,
3, 98, 111, 120,
6, 110, 101, 119, 97, 114, 114,
5, 108, 100, 108, 101, 110,
7, 108, 100, 101, 108, 101, 109, 97,
9, 108, 100, 101, 108, 101, 109, 46, 105, 49,
9, 108, 100, 101, 108, 101, 109, 46, 117, 49,
9, 108, 100, 101, 108, 101, 109, 46, 105, 50,
9, 108, 100, 101, 108, 101, 109, 46, 117, 50,
9, 108, 100, 101, 108, 101, 109, 46, 105, 52,
9, 108, 100, 101, 108, 101, 109, 46, 117, 52,
9, 108, 100, 101, 108, 101, 109, 46, 105, 56,
8, 108, 100, 101, 108, 101, 109, 46, 105,
9, 108, 100, 101, 108, 101, 109, 46, 114, 52,
9, 108, 100, 101, 108, 101, 109, 46, 114, 56,
10, 108, 100, 101, 108, 101, 109, 46, 114, 101, 102,
8, 115, 116, 101, 108, 101, 109, 46, 105,
9, 115, 116, 101, 108, 101, 109, 46, 105, 49,
9, 115, 116, 101, 108, 101, 109, 46, 105, 50,
9, 115, 116, 101, 108, 101, 109, 46, 105, 52,
9, 115, 116, 101, 108, 101, 109, 46, 105, 56,
9, 115, 116, 101, 108, 101, 109, 46, 114, 52,
9, 115, 116, 101, 108, 101, 109, 46, 114, 56,
10, 115, 116, 101, 108, 101, 109, 46, 114, 101, 102,
10, 108, 100, 101, 108, 101, 109, 46, 97, 110, 121,
10, 115, 116, 101, 108, 101, 109, 46, 97, 110, 121,
9, 117, 110, 98, 111, 120, 46, 97, 110, 121,
11, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 49,
11, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 49,
11, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 50,
11, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 50,
11, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 52,
11, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 52,
11, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 56,
11, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 56,
9, 114, 101, 102, 97, 110, 121, 118, 97, 108,
8, 99, 107, 102, 105, 110, 105, 116, 101,
8, 109, 107, 114, 101, 102, 97, 110, 121,
7, 108, 100, 116, 111, 107, 101, 110,
7, 99, 111, 110, 118, 46, 117, 50,
7, 99, 111, 110, 118, 46, 117, 49,
6, 99, 111, 110, 118, 46, 105,
10, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105,
10, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117,
7, 97, 100, 100, 46, 111, 118, 102,
10, 97, 100, 100, 46, 111, 118, 102, 46, 117, 110,
7, 109, 117, 108, 46, 111, 118, 102,
10, 109, 117, 108, 46, 111, 118, 102, 46, 117, 110,
7, 115, 117, 98, 46, 111, 118, 102,
10, 115, 117, 98, 46, 111, 118, 102, 46, 117, 110,
10, 101, 110, 100, 102, 105, 110, 97, 108, 108, 121,
5, 108, 101, 97, 118, 101,
7, 108, 101, 97, 118, 101, 46, 115,
7, 115, 116, 105, 110, 100, 46, 105,
6, 99, 111, 110, 118, 46, 117,
7, 97, 114, 103, 108, 105, 115, 116,
3, 99, 101, 113,
3, 99, 103, 116,
6, 99, 103, 116, 46, 117, 110,
3, 99, 108, 116,
6, 99, 108, 116, 46, 117, 110,
5, 108, 100, 102, 116, 110,
9, 108, 100, 118, 105, 114, 116, 102, 116, 110,
5, 108, 100, 97, 114, 103,
6, 108, 100, 97, 114, 103, 97,
5, 115, 116, 97, 114, 103,
5, 108, 100, 108, 111, 99,
6, 108, 100, 108, 111, 99, 97,
5, 115, 116, 108, 111, 99,
8, 108, 111, 99, 97, 108, 108, 111, 99,
9, 101, 110, 100, 102, 105, 108, 116, 101, 114,
10, 117, 110, 97, 108, 105, 103, 110, 101, 100, 46,
9, 118, 111, 108, 97, 116, 105, 108, 101, 46,
5, 116, 97, 105, 108, 46,
7, 105, 110, 105, 116, 111, 98, 106,
12, 99, 111, 110, 115, 116, 114, 97, 105, 110, 101, 100, 46,
5, 99, 112, 98, 108, 107,
7, 105, 110, 105, 116, 98, 108, 107,
3, 110, 111, 46,
7, 114, 101, 116, 104, 114, 111, 119,
6, 115, 105, 122, 101, 111, 102,
10, 114, 101, 102, 97, 110, 121, 116, 121, 112, 101,
9, 114, 101, 97, 100, 111, 110, 108, 121, 46,
};
names = new string [219];
for (int i = 0, p = 0; i < names.Length; i++) {
var buffer = new char [table [p++]];
for (int j = 0; j < buffer.Length; j++)
buffer [j] = (char) table [p++];
names [i] = new string (buffer);
}
}
}
}
}
#endregion
#region Mono.Cecil.Cil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil.Cil {
internal static class OpCodes {
internal static readonly OpCode [] OneByteOpCode = new OpCode [0xe0 + 1];
internal static readonly OpCode [] TwoBytesOpCode = new OpCode [0x1e + 1];
public static readonly OpCode Nop = new OpCode (
0xff << 0 | 0x00 << 8 | (byte) Code.Nop << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Break = new OpCode (
0xff << 0 | 0x01 << 8 | (byte) Code.Break << 16 | (byte) FlowControl.Break << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Ldarg_0 = new OpCode (
0xff << 0 | 0x02 << 8 | (byte) Code.Ldarg_0 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Ldarg_1 = new OpCode (
0xff << 0 | 0x03 << 8 | (byte) Code.Ldarg_1 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Ldarg_2 = new OpCode (
0xff << 0 | 0x04 << 8 | (byte) Code.Ldarg_2 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Ldarg_3 = new OpCode (
0xff << 0 | 0x05 << 8 | (byte) Code.Ldarg_3 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Ldloc_0 = new OpCode (
0xff << 0 | 0x06 << 8 | (byte) Code.Ldloc_0 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Ldloc_1 = new OpCode (
0xff << 0 | 0x07 << 8 | (byte) Code.Ldloc_1 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Ldloc_2 = new OpCode (
0xff << 0 | 0x08 << 8 | (byte) Code.Ldloc_2 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Ldloc_3 = new OpCode (
0xff << 0 | 0x09 << 8 | (byte) Code.Ldloc_3 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Stloc_0 = new OpCode (
0xff << 0 | 0x0a << 8 | (byte) Code.Stloc_0 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stloc_1 = new OpCode (
0xff << 0 | 0x0b << 8 | (byte) Code.Stloc_1 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stloc_2 = new OpCode (
0xff << 0 | 0x0c << 8 | (byte) Code.Stloc_2 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stloc_3 = new OpCode (
0xff << 0 | 0x0d << 8 | (byte) Code.Stloc_3 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Ldarg_S = new OpCode (
0xff << 0 | 0x0e << 8 | (byte) Code.Ldarg_S << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineArg << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Ldarga_S = new OpCode (
0xff << 0 | 0x0f << 8 | (byte) Code.Ldarga_S << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineArg << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Starg_S = new OpCode (
0xff << 0 | 0x10 << 8 | (byte) Code.Starg_S << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineArg << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Ldloc_S = new OpCode (
0xff << 0 | 0x11 << 8 | (byte) Code.Ldloc_S << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineVar << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Ldloca_S = new OpCode (
0xff << 0 | 0x12 << 8 | (byte) Code.Ldloca_S << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineVar << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Stloc_S = new OpCode (
0xff << 0 | 0x13 << 8 | (byte) Code.Stloc_S << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineVar << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Ldnull = new OpCode (
0xff << 0 | 0x14 << 8 | (byte) Code.Ldnull << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushref << 24);
public static readonly OpCode Ldc_I4_M1 = new OpCode (
0xff << 0 | 0x15 << 8 | (byte) Code.Ldc_I4_M1 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldc_I4_0 = new OpCode (
0xff << 0 | 0x16 << 8 | (byte) Code.Ldc_I4_0 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldc_I4_1 = new OpCode (
0xff << 0 | 0x17 << 8 | (byte) Code.Ldc_I4_1 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldc_I4_2 = new OpCode (
0xff << 0 | 0x18 << 8 | (byte) Code.Ldc_I4_2 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldc_I4_3 = new OpCode (
0xff << 0 | 0x19 << 8 | (byte) Code.Ldc_I4_3 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldc_I4_4 = new OpCode (
0xff << 0 | 0x1a << 8 | (byte) Code.Ldc_I4_4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldc_I4_5 = new OpCode (
0xff << 0 | 0x1b << 8 | (byte) Code.Ldc_I4_5 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldc_I4_6 = new OpCode (
0xff << 0 | 0x1c << 8 | (byte) Code.Ldc_I4_6 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldc_I4_7 = new OpCode (
0xff << 0 | 0x1d << 8 | (byte) Code.Ldc_I4_7 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldc_I4_8 = new OpCode (
0xff << 0 | 0x1e << 8 | (byte) Code.Ldc_I4_8 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldc_I4_S = new OpCode (
0xff << 0 | 0x1f << 8 | (byte) Code.Ldc_I4_S << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineI << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldc_I4 = new OpCode (
0xff << 0 | 0x20 << 8 | (byte) Code.Ldc_I4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineI << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldc_I8 = new OpCode (
0xff << 0 | 0x21 << 8 | (byte) Code.Ldc_I8 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineI8 << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi8 << 24);
public static readonly OpCode Ldc_R4 = new OpCode (
0xff << 0 | 0x22 << 8 | (byte) Code.Ldc_R4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.ShortInlineR << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushr4 << 24);
public static readonly OpCode Ldc_R8 = new OpCode (
0xff << 0 | 0x23 << 8 | (byte) Code.Ldc_R8 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineR << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushr8 << 24);
public static readonly OpCode Dup = new OpCode (
0xff << 0 | 0x25 << 8 | (byte) Code.Dup << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push1_push1 << 24);
public static readonly OpCode Pop = new OpCode (
0xff << 0 | 0x26 << 8 | (byte) Code.Pop << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Jmp = new OpCode (
0xff << 0 | 0x27 << 8 | (byte) Code.Jmp << 16 | (byte) FlowControl.Call << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineMethod << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Call = new OpCode (
0xff << 0 | 0x28 << 8 | (byte) Code.Call << 16 | (byte) FlowControl.Call << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineMethod << 8 | (byte) StackBehaviour.Varpop << 16 | (byte) StackBehaviour.Varpush << 24);
public static readonly OpCode Calli = new OpCode (
0xff << 0 | 0x29 << 8 | (byte) Code.Calli << 16 | (byte) FlowControl.Call << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineSig << 8 | (byte) StackBehaviour.Varpop << 16 | (byte) StackBehaviour.Varpush << 24);
public static readonly OpCode Ret = new OpCode (
0xff << 0 | 0x2a << 8 | (byte) Code.Ret << 16 | (byte) FlowControl.Return << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Varpop << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Br_S = new OpCode (
0xff << 0 | 0x2b << 8 | (byte) Code.Br_S << 16 | (byte) FlowControl.Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Brfalse_S = new OpCode (
0xff << 0 | 0x2c << 8 | (byte) Code.Brfalse_S << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Brtrue_S = new OpCode (
0xff << 0 | 0x2d << 8 | (byte) Code.Brtrue_S << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Beq_S = new OpCode (
0xff << 0 | 0x2e << 8 | (byte) Code.Beq_S << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Bge_S = new OpCode (
0xff << 0 | 0x2f << 8 | (byte) Code.Bge_S << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Bgt_S = new OpCode (
0xff << 0 | 0x30 << 8 | (byte) Code.Bgt_S << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Ble_S = new OpCode (
0xff << 0 | 0x31 << 8 | (byte) Code.Ble_S << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Blt_S = new OpCode (
0xff << 0 | 0x32 << 8 | (byte) Code.Blt_S << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Bne_Un_S = new OpCode (
0xff << 0 | 0x33 << 8 | (byte) Code.Bne_Un_S << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Bge_Un_S = new OpCode (
0xff << 0 | 0x34 << 8 | (byte) Code.Bge_Un_S << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Bgt_Un_S = new OpCode (
0xff << 0 | 0x35 << 8 | (byte) Code.Bgt_Un_S << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Ble_Un_S = new OpCode (
0xff << 0 | 0x36 << 8 | (byte) Code.Ble_Un_S << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Blt_Un_S = new OpCode (
0xff << 0 | 0x37 << 8 | (byte) Code.Blt_Un_S << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Br = new OpCode (
0xff << 0 | 0x38 << 8 | (byte) Code.Br << 16 | (byte) FlowControl.Branch << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Brfalse = new OpCode (
0xff << 0 | 0x39 << 8 | (byte) Code.Brfalse << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Brtrue = new OpCode (
0xff << 0 | 0x3a << 8 | (byte) Code.Brtrue << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Beq = new OpCode (
0xff << 0 | 0x3b << 8 | (byte) Code.Beq << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Bge = new OpCode (
0xff << 0 | 0x3c << 8 | (byte) Code.Bge << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Bgt = new OpCode (
0xff << 0 | 0x3d << 8 | (byte) Code.Bgt << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Ble = new OpCode (
0xff << 0 | 0x3e << 8 | (byte) Code.Ble << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Blt = new OpCode (
0xff << 0 | 0x3f << 8 | (byte) Code.Blt << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Bne_Un = new OpCode (
0xff << 0 | 0x40 << 8 | (byte) Code.Bne_Un << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Bge_Un = new OpCode (
0xff << 0 | 0x41 << 8 | (byte) Code.Bge_Un << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Bgt_Un = new OpCode (
0xff << 0 | 0x42 << 8 | (byte) Code.Bgt_Un << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Ble_Un = new OpCode (
0xff << 0 | 0x43 << 8 | (byte) Code.Ble_Un << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Blt_Un = new OpCode (
0xff << 0 | 0x44 << 8 | (byte) Code.Blt_Un << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Switch = new OpCode (
0xff << 0 | 0x45 << 8 | (byte) Code.Switch << 16 | (byte) FlowControl.Cond_Branch << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineSwitch << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Ldind_I1 = new OpCode (
0xff << 0 | 0x46 << 8 | (byte) Code.Ldind_I1 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldind_U1 = new OpCode (
0xff << 0 | 0x47 << 8 | (byte) Code.Ldind_U1 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldind_I2 = new OpCode (
0xff << 0 | 0x48 << 8 | (byte) Code.Ldind_I2 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldind_U2 = new OpCode (
0xff << 0 | 0x49 << 8 | (byte) Code.Ldind_U2 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldind_I4 = new OpCode (
0xff << 0 | 0x4a << 8 | (byte) Code.Ldind_I4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldind_U4 = new OpCode (
0xff << 0 | 0x4b << 8 | (byte) Code.Ldind_U4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldind_I8 = new OpCode (
0xff << 0 | 0x4c << 8 | (byte) Code.Ldind_I8 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi8 << 24);
public static readonly OpCode Ldind_I = new OpCode (
0xff << 0 | 0x4d << 8 | (byte) Code.Ldind_I << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldind_R4 = new OpCode (
0xff << 0 | 0x4e << 8 | (byte) Code.Ldind_R4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushr4 << 24);
public static readonly OpCode Ldind_R8 = new OpCode (
0xff << 0 | 0x4f << 8 | (byte) Code.Ldind_R8 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushr8 << 24);
public static readonly OpCode Ldind_Ref = new OpCode (
0xff << 0 | 0x50 << 8 | (byte) Code.Ldind_Ref << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushref << 24);
public static readonly OpCode Stind_Ref = new OpCode (
0xff << 0 | 0x51 << 8 | (byte) Code.Stind_Ref << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stind_I1 = new OpCode (
0xff << 0 | 0x52 << 8 | (byte) Code.Stind_I1 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stind_I2 = new OpCode (
0xff << 0 | 0x53 << 8 | (byte) Code.Stind_I2 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stind_I4 = new OpCode (
0xff << 0 | 0x54 << 8 | (byte) Code.Stind_I4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stind_I8 = new OpCode (
0xff << 0 | 0x55 << 8 | (byte) Code.Stind_I8 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popi8 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stind_R4 = new OpCode (
0xff << 0 | 0x56 << 8 | (byte) Code.Stind_R4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popr4 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stind_R8 = new OpCode (
0xff << 0 | 0x57 << 8 | (byte) Code.Stind_R8 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popr8 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Add = new OpCode (
0xff << 0 | 0x58 << 8 | (byte) Code.Add << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Sub = new OpCode (
0xff << 0 | 0x59 << 8 | (byte) Code.Sub << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Mul = new OpCode (
0xff << 0 | 0x5a << 8 | (byte) Code.Mul << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Div = new OpCode (
0xff << 0 | 0x5b << 8 | (byte) Code.Div << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Div_Un = new OpCode (
0xff << 0 | 0x5c << 8 | (byte) Code.Div_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Rem = new OpCode (
0xff << 0 | 0x5d << 8 | (byte) Code.Rem << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Rem_Un = new OpCode (
0xff << 0 | 0x5e << 8 | (byte) Code.Rem_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode And = new OpCode (
0xff << 0 | 0x5f << 8 | (byte) Code.And << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Or = new OpCode (
0xff << 0 | 0x60 << 8 | (byte) Code.Or << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Xor = new OpCode (
0xff << 0 | 0x61 << 8 | (byte) Code.Xor << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Shl = new OpCode (
0xff << 0 | 0x62 << 8 | (byte) Code.Shl << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Shr = new OpCode (
0xff << 0 | 0x63 << 8 | (byte) Code.Shr << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Shr_Un = new OpCode (
0xff << 0 | 0x64 << 8 | (byte) Code.Shr_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Neg = new OpCode (
0xff << 0 | 0x65 << 8 | (byte) Code.Neg << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Not = new OpCode (
0xff << 0 | 0x66 << 8 | (byte) Code.Not << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Conv_I1 = new OpCode (
0xff << 0 | 0x67 << 8 | (byte) Code.Conv_I1 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_I2 = new OpCode (
0xff << 0 | 0x68 << 8 | (byte) Code.Conv_I2 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_I4 = new OpCode (
0xff << 0 | 0x69 << 8 | (byte) Code.Conv_I4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_I8 = new OpCode (
0xff << 0 | 0x6a << 8 | (byte) Code.Conv_I8 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi8 << 24);
public static readonly OpCode Conv_R4 = new OpCode (
0xff << 0 | 0x6b << 8 | (byte) Code.Conv_R4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushr4 << 24);
public static readonly OpCode Conv_R8 = new OpCode (
0xff << 0 | 0x6c << 8 | (byte) Code.Conv_R8 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushr8 << 24);
public static readonly OpCode Conv_U4 = new OpCode (
0xff << 0 | 0x6d << 8 | (byte) Code.Conv_U4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_U8 = new OpCode (
0xff << 0 | 0x6e << 8 | (byte) Code.Conv_U8 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi8 << 24);
public static readonly OpCode Callvirt = new OpCode (
0xff << 0 | 0x6f << 8 | (byte) Code.Callvirt << 16 | (byte) FlowControl.Call << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineMethod << 8 | (byte) StackBehaviour.Varpop << 16 | (byte) StackBehaviour.Varpush << 24);
public static readonly OpCode Cpobj = new OpCode (
0xff << 0 | 0x70 << 8 | (byte) Code.Cpobj << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popi_popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Ldobj = new OpCode (
0xff << 0 | 0x71 << 8 | (byte) Code.Ldobj << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Ldstr = new OpCode (
0xff << 0 | 0x72 << 8 | (byte) Code.Ldstr << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineString << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushref << 24);
public static readonly OpCode Newobj = new OpCode (
0xff << 0 | 0x73 << 8 | (byte) Code.Newobj << 16 | (byte) FlowControl.Call << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineMethod << 8 | (byte) StackBehaviour.Varpop << 16 | (byte) StackBehaviour.Pushref << 24);
public static readonly OpCode Castclass = new OpCode (
0xff << 0 | 0x74 << 8 | (byte) Code.Castclass << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Pushref << 24);
public static readonly OpCode Isinst = new OpCode (
0xff << 0 | 0x75 << 8 | (byte) Code.Isinst << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_R_Un = new OpCode (
0xff << 0 | 0x76 << 8 | (byte) Code.Conv_R_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushr8 << 24);
public static readonly OpCode Unbox = new OpCode (
0xff << 0 | 0x79 << 8 | (byte) Code.Unbox << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Throw = new OpCode (
0xff << 0 | 0x7a << 8 | (byte) Code.Throw << 16 | (byte) FlowControl.Throw << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Ldfld = new OpCode (
0xff << 0 | 0x7b << 8 | (byte) Code.Ldfld << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineField << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Ldflda = new OpCode (
0xff << 0 | 0x7c << 8 | (byte) Code.Ldflda << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineField << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Stfld = new OpCode (
0xff << 0 | 0x7d << 8 | (byte) Code.Stfld << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineField << 8 | (byte) StackBehaviour.Popref_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Ldsfld = new OpCode (
0xff << 0 | 0x7e << 8 | (byte) Code.Ldsfld << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineField << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Ldsflda = new OpCode (
0xff << 0 | 0x7f << 8 | (byte) Code.Ldsflda << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineField << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Stsfld = new OpCode (
0xff << 0 | 0x80 << 8 | (byte) Code.Stsfld << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineField << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stobj = new OpCode (
0xff << 0 | 0x81 << 8 | (byte) Code.Stobj << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popi_pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Conv_Ovf_I1_Un = new OpCode (
0xff << 0 | 0x82 << 8 | (byte) Code.Conv_Ovf_I1_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_Ovf_I2_Un = new OpCode (
0xff << 0 | 0x83 << 8 | (byte) Code.Conv_Ovf_I2_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_Ovf_I4_Un = new OpCode (
0xff << 0 | 0x84 << 8 | (byte) Code.Conv_Ovf_I4_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_Ovf_I8_Un = new OpCode (
0xff << 0 | 0x85 << 8 | (byte) Code.Conv_Ovf_I8_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi8 << 24);
public static readonly OpCode Conv_Ovf_U1_Un = new OpCode (
0xff << 0 | 0x86 << 8 | (byte) Code.Conv_Ovf_U1_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_Ovf_U2_Un = new OpCode (
0xff << 0 | 0x87 << 8 | (byte) Code.Conv_Ovf_U2_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_Ovf_U4_Un = new OpCode (
0xff << 0 | 0x88 << 8 | (byte) Code.Conv_Ovf_U4_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_Ovf_U8_Un = new OpCode (
0xff << 0 | 0x89 << 8 | (byte) Code.Conv_Ovf_U8_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi8 << 24);
public static readonly OpCode Conv_Ovf_I_Un = new OpCode (
0xff << 0 | 0x8a << 8 | (byte) Code.Conv_Ovf_I_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_Ovf_U_Un = new OpCode (
0xff << 0 | 0x8b << 8 | (byte) Code.Conv_Ovf_U_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Box = new OpCode (
0xff << 0 | 0x8c << 8 | (byte) Code.Box << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushref << 24);
public static readonly OpCode Newarr = new OpCode (
0xff << 0 | 0x8d << 8 | (byte) Code.Newarr << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushref << 24);
public static readonly OpCode Ldlen = new OpCode (
0xff << 0 | 0x8e << 8 | (byte) Code.Ldlen << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldelema = new OpCode (
0xff << 0 | 0x8f << 8 | (byte) Code.Ldelema << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldelem_I1 = new OpCode (
0xff << 0 | 0x90 << 8 | (byte) Code.Ldelem_I1 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldelem_U1 = new OpCode (
0xff << 0 | 0x91 << 8 | (byte) Code.Ldelem_U1 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldelem_I2 = new OpCode (
0xff << 0 | 0x92 << 8 | (byte) Code.Ldelem_I2 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldelem_U2 = new OpCode (
0xff << 0 | 0x93 << 8 | (byte) Code.Ldelem_U2 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldelem_I4 = new OpCode (
0xff << 0 | 0x94 << 8 | (byte) Code.Ldelem_I4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldelem_U4 = new OpCode (
0xff << 0 | 0x95 << 8 | (byte) Code.Ldelem_U4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldelem_I8 = new OpCode (
0xff << 0 | 0x96 << 8 | (byte) Code.Ldelem_I8 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi8 << 24);
public static readonly OpCode Ldelem_I = new OpCode (
0xff << 0 | 0x97 << 8 | (byte) Code.Ldelem_I << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldelem_R4 = new OpCode (
0xff << 0 | 0x98 << 8 | (byte) Code.Ldelem_R4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushr4 << 24);
public static readonly OpCode Ldelem_R8 = new OpCode (
0xff << 0 | 0x99 << 8 | (byte) Code.Ldelem_R8 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushr8 << 24);
public static readonly OpCode Ldelem_Ref = new OpCode (
0xff << 0 | 0x9a << 8 | (byte) Code.Ldelem_Ref << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushref << 24);
public static readonly OpCode Stelem_I = new OpCode (
0xff << 0 | 0x9b << 8 | (byte) Code.Stelem_I << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi_popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stelem_I1 = new OpCode (
0xff << 0 | 0x9c << 8 | (byte) Code.Stelem_I1 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi_popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stelem_I2 = new OpCode (
0xff << 0 | 0x9d << 8 | (byte) Code.Stelem_I2 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi_popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stelem_I4 = new OpCode (
0xff << 0 | 0x9e << 8 | (byte) Code.Stelem_I4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi_popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stelem_I8 = new OpCode (
0xff << 0 | 0x9f << 8 | (byte) Code.Stelem_I8 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi_popi8 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stelem_R4 = new OpCode (
0xff << 0 | 0xa0 << 8 | (byte) Code.Stelem_R4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi_popr4 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stelem_R8 = new OpCode (
0xff << 0 | 0xa1 << 8 | (byte) Code.Stelem_R8 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi_popr8 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stelem_Ref = new OpCode (
0xff << 0 | 0xa2 << 8 | (byte) Code.Stelem_Ref << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi_popref << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Ldelem_Any = new OpCode (
0xff << 0 | 0xa3 << 8 | (byte) Code.Ldelem_Any << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Stelem_Any = new OpCode (
0xff << 0 | 0xa4 << 8 | (byte) Code.Stelem_Any << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popref_popi_popref << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Unbox_Any = new OpCode (
0xff << 0 | 0xa5 << 8 | (byte) Code.Unbox_Any << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Conv_Ovf_I1 = new OpCode (
0xff << 0 | 0xb3 << 8 | (byte) Code.Conv_Ovf_I1 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_Ovf_U1 = new OpCode (
0xff << 0 | 0xb4 << 8 | (byte) Code.Conv_Ovf_U1 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_Ovf_I2 = new OpCode (
0xff << 0 | 0xb5 << 8 | (byte) Code.Conv_Ovf_I2 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_Ovf_U2 = new OpCode (
0xff << 0 | 0xb6 << 8 | (byte) Code.Conv_Ovf_U2 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_Ovf_I4 = new OpCode (
0xff << 0 | 0xb7 << 8 | (byte) Code.Conv_Ovf_I4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_Ovf_U4 = new OpCode (
0xff << 0 | 0xb8 << 8 | (byte) Code.Conv_Ovf_U4 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_Ovf_I8 = new OpCode (
0xff << 0 | 0xb9 << 8 | (byte) Code.Conv_Ovf_I8 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi8 << 24);
public static readonly OpCode Conv_Ovf_U8 = new OpCode (
0xff << 0 | 0xba << 8 | (byte) Code.Conv_Ovf_U8 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi8 << 24);
public static readonly OpCode Refanyval = new OpCode (
0xff << 0 | 0xc2 << 8 | (byte) Code.Refanyval << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ckfinite = new OpCode (
0xff << 0 | 0xc3 << 8 | (byte) Code.Ckfinite << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushr8 << 24);
public static readonly OpCode Mkrefany = new OpCode (
0xff << 0 | 0xc6 << 8 | (byte) Code.Mkrefany << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Ldtoken = new OpCode (
0xff << 0 | 0xd0 << 8 | (byte) Code.Ldtoken << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineTok << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_U2 = new OpCode (
0xff << 0 | 0xd1 << 8 | (byte) Code.Conv_U2 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_U1 = new OpCode (
0xff << 0 | 0xd2 << 8 | (byte) Code.Conv_U1 << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_I = new OpCode (
0xff << 0 | 0xd3 << 8 | (byte) Code.Conv_I << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_Ovf_I = new OpCode (
0xff << 0 | 0xd4 << 8 | (byte) Code.Conv_Ovf_I << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Conv_Ovf_U = new OpCode (
0xff << 0 | 0xd5 << 8 | (byte) Code.Conv_Ovf_U << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Add_Ovf = new OpCode (
0xff << 0 | 0xd6 << 8 | (byte) Code.Add_Ovf << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Add_Ovf_Un = new OpCode (
0xff << 0 | 0xd7 << 8 | (byte) Code.Add_Ovf_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Mul_Ovf = new OpCode (
0xff << 0 | 0xd8 << 8 | (byte) Code.Mul_Ovf << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Mul_Ovf_Un = new OpCode (
0xff << 0 | 0xd9 << 8 | (byte) Code.Mul_Ovf_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Sub_Ovf = new OpCode (
0xff << 0 | 0xda << 8 | (byte) Code.Sub_Ovf << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Sub_Ovf_Un = new OpCode (
0xff << 0 | 0xdb << 8 | (byte) Code.Sub_Ovf_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Endfinally = new OpCode (
0xff << 0 | 0xdc << 8 | (byte) Code.Endfinally << 16 | (byte) FlowControl.Return << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Leave = new OpCode (
0xff << 0 | 0xdd << 8 | (byte) Code.Leave << 16 | (byte) FlowControl.Branch << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.PopAll << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Leave_S = new OpCode (
0xff << 0 | 0xde << 8 | (byte) Code.Leave_S << 16 | (byte) FlowControl.Branch << 24,
(byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.PopAll << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Stind_I = new OpCode (
0xff << 0 | 0xdf << 8 | (byte) Code.Stind_I << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Conv_U = new OpCode (
0xff << 0 | 0xe0 << 8 | (byte) Code.Conv_U << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Arglist = new OpCode (
0xfe << 0 | 0x00 << 8 | (byte) Code.Arglist << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ceq = new OpCode (
0xfe << 0 | 0x01 << 8 | (byte) Code.Ceq << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Cgt = new OpCode (
0xfe << 0 | 0x02 << 8 | (byte) Code.Cgt << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Cgt_Un = new OpCode (
0xfe << 0 | 0x03 << 8 | (byte) Code.Cgt_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Clt = new OpCode (
0xfe << 0 | 0x04 << 8 | (byte) Code.Clt << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Clt_Un = new OpCode (
0xfe << 0 | 0x05 << 8 | (byte) Code.Clt_Un << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldftn = new OpCode (
0xfe << 0 | 0x06 << 8 | (byte) Code.Ldftn << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineMethod << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldvirtftn = new OpCode (
0xfe << 0 | 0x07 << 8 | (byte) Code.Ldvirtftn << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineMethod << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Ldarg = new OpCode (
0xfe << 0 | 0x09 << 8 | (byte) Code.Ldarg << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineArg << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Ldarga = new OpCode (
0xfe << 0 | 0x0a << 8 | (byte) Code.Ldarga << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineArg << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Starg = new OpCode (
0xfe << 0 | 0x0b << 8 | (byte) Code.Starg << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineArg << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Ldloc = new OpCode (
0xfe << 0 | 0x0c << 8 | (byte) Code.Ldloc << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineVar << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24);
public static readonly OpCode Ldloca = new OpCode (
0xfe << 0 | 0x0d << 8 | (byte) Code.Ldloca << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineVar << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Stloc = new OpCode (
0xfe << 0 | 0x0e << 8 | (byte) Code.Stloc << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineVar << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Localloc = new OpCode (
0xfe << 0 | 0x0f << 8 | (byte) Code.Localloc << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Endfilter = new OpCode (
0xfe << 0 | 0x11 << 8 | (byte) Code.Endfilter << 16 | (byte) FlowControl.Return << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Unaligned = new OpCode (
0xfe << 0 | 0x12 << 8 | (byte) Code.Unaligned << 16 | (byte) FlowControl.Meta << 24,
(byte) OpCodeType.Prefix << 0 | (byte) OperandType.ShortInlineI << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Volatile = new OpCode (
0xfe << 0 | 0x13 << 8 | (byte) Code.Volatile << 16 | (byte) FlowControl.Meta << 24,
(byte) OpCodeType.Prefix << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Tail = new OpCode (
0xfe << 0 | 0x14 << 8 | (byte) Code.Tail << 16 | (byte) FlowControl.Meta << 24,
(byte) OpCodeType.Prefix << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Initobj = new OpCode (
0xfe << 0 | 0x15 << 8 | (byte) Code.Initobj << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Constrained = new OpCode (
0xfe << 0 | 0x16 << 8 | (byte) Code.Constrained << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Prefix << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Cpblk = new OpCode (
0xfe << 0 | 0x17 << 8 | (byte) Code.Cpblk << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popi_popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Initblk = new OpCode (
0xfe << 0 | 0x18 << 8 | (byte) Code.Initblk << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popi_popi << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode No = new OpCode (
0xfe << 0 | 0x19 << 8 | (byte) Code.No << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Prefix << 0 | (byte) OperandType.ShortInlineI << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Rethrow = new OpCode (
0xfe << 0 | 0x1a << 8 | (byte) Code.Rethrow << 16 | (byte) FlowControl.Throw << 24,
(byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24);
public static readonly OpCode Sizeof = new OpCode (
0xfe << 0 | 0x1c << 8 | (byte) Code.Sizeof << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Refanytype = new OpCode (
0xfe << 0 | 0x1d << 8 | (byte) Code.Refanytype << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24);
public static readonly OpCode Readonly = new OpCode (
0xfe << 0 | 0x1e << 8 | (byte) Code.Readonly << 16 | (byte) FlowControl.Next << 24,
(byte) OpCodeType.Prefix << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24);
}
}
}
#endregion
#region Mono.Cecil.Cil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using Mono.Cecil.Metadata;
using Mono.Cecil.PE;
namespace Mono.Cecil.Cil {
internal sealed class PortablePdbReaderProvider : ISymbolReaderProvider {
public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName)
{
Mixin.CheckModule (module);
Mixin.CheckFileName (fileName);
var file = File.OpenRead (Mixin.GetPdbFileName (fileName));
return GetSymbolReader (module, Disposable.Owned (file as Stream), file.Name);
}
public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream)
{
Mixin.CheckModule (module);
Mixin.CheckStream (symbolStream);
return GetSymbolReader (module, Disposable.NotOwned (symbolStream), symbolStream.GetFileName ());
}
ISymbolReader GetSymbolReader (ModuleDefinition module, Disposable<Stream> symbolStream, string fileName)
{
return new PortablePdbReader (ImageReader.ReadPortablePdb (symbolStream, fileName), module);
}
}
internal sealed class PortablePdbReader : ISymbolReader {
readonly Image image;
readonly ModuleDefinition module;
readonly MetadataReader reader;
readonly MetadataReader debug_reader;
bool IsEmbedded { get { return reader.image == debug_reader.image; } }
internal PortablePdbReader (Image image, ModuleDefinition module)
{
this.image = image;
this.module = module;
this.reader = module.reader;
this.debug_reader = new MetadataReader (image, module, this.reader);
}
#if !READ_ONLY
public ISymbolWriterProvider GetWriterProvider ()
{
return new PortablePdbWriterProvider ();
}
#endif
public bool ProcessDebugHeader (ImageDebugHeader header)
{
if (image == module.Image)
return true;
var entry = header.GetCodeViewEntry ();
if (entry == null)
return false;
var data = entry.Data;
if (data.Length < 24)
return false;
var magic = ReadInt32 (data, 0);
if (magic != 0x53445352)
return false;
var buffer = new byte [16];
Buffer.BlockCopy (data, 4, buffer, 0, 16);
var module_guid = new Guid (buffer);
Buffer.BlockCopy (image.PdbHeap.Id, 0, buffer, 0, 16);
var pdb_guid = new Guid (buffer);
if (module_guid != pdb_guid)
return false;
ReadModule ();
return true;
}
static int ReadInt32 (byte [] bytes, int start)
{
return (bytes [start]
| (bytes [start + 1] << 8)
| (bytes [start + 2] << 16)
| (bytes [start + 3] << 24));
}
void ReadModule ()
{
module.custom_infos = debug_reader.GetCustomDebugInformation (module);
}
public MethodDebugInformation Read (MethodDefinition method)
{
var info = new MethodDebugInformation (method);
ReadSequencePoints (info);
ReadScope (info);
ReadStateMachineKickOffMethod (info);
ReadCustomDebugInformations (info);
return info;
}
void ReadSequencePoints (MethodDebugInformation method_info)
{
method_info.sequence_points = debug_reader.ReadSequencePoints (method_info.method);
}
void ReadScope (MethodDebugInformation method_info)
{
method_info.scope = debug_reader.ReadScope (method_info.method);
}
void ReadStateMachineKickOffMethod (MethodDebugInformation method_info)
{
method_info.kickoff_method = debug_reader.ReadStateMachineKickoffMethod (method_info.method);
}
void ReadCustomDebugInformations (MethodDebugInformation info)
{
info.method.custom_infos = debug_reader.GetCustomDebugInformation (info.method);
}
public void Dispose ()
{
if (IsEmbedded)
return;
image.Dispose ();
}
}
internal sealed class EmbeddedPortablePdbReaderProvider : ISymbolReaderProvider {
public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName)
{
Mixin.CheckModule (module);
var header = module.GetDebugHeader ();
var entry = header.GetEmbeddedPortablePdbEntry ();
if (entry == null)
throw new InvalidOperationException ();
return new EmbeddedPortablePdbReader (
(PortablePdbReader) new PortablePdbReaderProvider ().GetSymbolReader (module, GetPortablePdbStream (entry)));
}
static Stream GetPortablePdbStream (ImageDebugHeaderEntry entry)
{
var compressed_stream = new MemoryStream (entry.Data);
var reader = new BinaryStreamReader (compressed_stream);
reader.ReadInt32 (); // signature
var length = reader.ReadInt32 ();
var decompressed_stream = new MemoryStream (length);
using (var deflate_stream = new DeflateStream (compressed_stream, CompressionMode.Decompress, leaveOpen: true))
deflate_stream.CopyTo (decompressed_stream);
return decompressed_stream;
}
public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream)
{
throw new NotSupportedException ();
}
}
internal sealed class EmbeddedPortablePdbReader : ISymbolReader
{
private readonly PortablePdbReader reader;
internal EmbeddedPortablePdbReader (PortablePdbReader reader)
{
if (reader == null)
throw new ArgumentNullException ();
this.reader = reader;
}
#if !READ_ONLY
public ISymbolWriterProvider GetWriterProvider ()
{
return new EmbeddedPortablePdbWriterProvider ();
}
#endif
public bool ProcessDebugHeader (ImageDebugHeader header)
{
return reader.ProcessDebugHeader (header);
}
public MethodDebugInformation Read (MethodDefinition method)
{
return reader.Read (method);
}
public void Dispose ()
{
reader.Dispose ();
}
}
#if !READ_ONLY
internal sealed class PortablePdbWriterProvider : ISymbolWriterProvider
{
public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName)
{
Mixin.CheckModule (module);
Mixin.CheckFileName (fileName);
var file = File.OpenWrite (Mixin.GetPdbFileName (fileName));
return GetSymbolWriter (module, Disposable.Owned (file as Stream));
}
public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream)
{
Mixin.CheckModule (module);
Mixin.CheckStream (symbolStream);
return GetSymbolWriter (module, Disposable.NotOwned (symbolStream));
}
ISymbolWriter GetSymbolWriter (ModuleDefinition module, Disposable<Stream> stream)
{
var metadata = new MetadataBuilder (module, this);
var writer = ImageWriter.CreateDebugWriter (module, metadata, stream);
return new PortablePdbWriter (metadata, module, writer);
}
}
interface IMetadataSymbolWriter : ISymbolWriter {
void SetMetadata (MetadataBuilder metadata);
void WriteModule ();
}
internal sealed class PortablePdbWriter : ISymbolWriter, IMetadataSymbolWriter {
readonly MetadataBuilder pdb_metadata;
readonly ModuleDefinition module;
readonly ImageWriter writer;
MetadataBuilder module_metadata;
bool IsEmbedded { get { return writer == null; } }
internal PortablePdbWriter (MetadataBuilder pdb_metadata, ModuleDefinition module)
{
this.pdb_metadata = pdb_metadata;
this.module = module;
}
internal PortablePdbWriter (MetadataBuilder pdb_metadata, ModuleDefinition module, ImageWriter writer)
: this (pdb_metadata, module)
{
this.writer = writer;
}
void IMetadataSymbolWriter.SetMetadata (MetadataBuilder metadata)
{
this.module_metadata = metadata;
if (module_metadata != pdb_metadata)
this.pdb_metadata.metadata_builder = metadata;
}
void IMetadataSymbolWriter.WriteModule ()
{
pdb_metadata.AddCustomDebugInformations (module);
}
public ISymbolReaderProvider GetReaderProvider ()
{
return new PortablePdbReaderProvider ();
}
public ImageDebugHeader GetDebugHeader ()
{
if (IsEmbedded)
return new ImageDebugHeader ();
var directory = new ImageDebugDirectory () {
MajorVersion = 256,
MinorVersion = 20557,
Type = ImageDebugType.CodeView,
TimeDateStamp = (int) module.timestamp,
};
var buffer = new ByteBuffer ();
// RSDS
buffer.WriteUInt32 (0x53445352);
// Module ID
buffer.WriteBytes (module.Mvid.ToByteArray ());
// PDB Age
buffer.WriteUInt32 (1);
// PDB Path
var filename = writer.BaseStream.GetFileName ();
if (!string.IsNullOrEmpty (filename))
filename = Path.GetFileName (filename);
buffer.WriteBytes (System.Text.Encoding.UTF8.GetBytes (filename));
buffer.WriteByte (0);
var data = new byte [buffer.length];
Buffer.BlockCopy (buffer.buffer, 0, data, 0, buffer.length);
directory.SizeOfData = data.Length;
return new ImageDebugHeader (new ImageDebugHeaderEntry (directory, data));
}
public void Write (MethodDebugInformation info)
{
CheckMethodDebugInformationTable ();
pdb_metadata.AddMethodDebugInformation (info);
}
void CheckMethodDebugInformationTable ()
{
var mdi = pdb_metadata.table_heap.GetTable<MethodDebugInformationTable> (Table.MethodDebugInformation);
if (mdi.length > 0)
return;
// The MethodDebugInformation table has the same length as the Method table
mdi.rows = new Row<uint, uint> [module_metadata.method_rid - 1];
mdi.length = mdi.rows.Length;
}
public void Dispose ()
{
if (IsEmbedded)
return;
WritePdbFile ();
}
void WritePdbFile ()
{
WritePdbHeap ();
WriteTableHeap ();
writer.BuildMetadataTextMap ();
writer.WriteMetadataHeader ();
writer.WriteMetadata ();
writer.Flush ();
writer.stream.Dispose ();
}
void WritePdbHeap ()
{
var pdb_heap = pdb_metadata.pdb_heap;
pdb_heap.WriteBytes (module.Mvid.ToByteArray ());
pdb_heap.WriteUInt32 (module_metadata.timestamp);
pdb_heap.WriteUInt32 (module_metadata.entry_point.ToUInt32 ());
var table_heap = module_metadata.table_heap;
var tables = table_heap.tables;
ulong valid = 0;
for (int i = 0; i < tables.Length; i++) {
if (tables [i] == null || tables [i].Length == 0)
continue;
valid |= (1UL << i);
}
pdb_heap.WriteUInt64 (valid);
for (int i = 0; i < tables.Length; i++) {
if (tables [i] == null || tables [i].Length == 0)
continue;
pdb_heap.WriteUInt32 ((uint) tables [i].Length);
}
}
void WriteTableHeap ()
{
pdb_metadata.table_heap.string_offsets = pdb_metadata.string_heap.WriteStrings ();
pdb_metadata.table_heap.ComputeTableInformations ();
pdb_metadata.table_heap.WriteTableHeap ();
}
}
internal sealed class EmbeddedPortablePdbWriterProvider : ISymbolWriterProvider {
public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName)
{
Mixin.CheckModule (module);
Mixin.CheckFileName (fileName);
var stream = new MemoryStream ();
var pdb_writer = (PortablePdbWriter) new PortablePdbWriterProvider ().GetSymbolWriter (module, stream);
return new EmbeddedPortablePdbWriter (stream, pdb_writer);
}
public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream)
{
throw new NotSupportedException ();
}
}
internal sealed class EmbeddedPortablePdbWriter : ISymbolWriter, IMetadataSymbolWriter {
readonly Stream stream;
readonly PortablePdbWriter writer;
internal EmbeddedPortablePdbWriter (Stream stream, PortablePdbWriter writer)
{
this.stream = stream;
this.writer = writer;
}
public ISymbolReaderProvider GetReaderProvider ()
{
return new EmbeddedPortablePdbReaderProvider ();
}
public ImageDebugHeader GetDebugHeader ()
{
writer.Dispose ();
var directory = new ImageDebugDirectory {
Type = ImageDebugType.EmbeddedPortablePdb,
MajorVersion = 0x0100,
MinorVersion = 0x0100,
};
var data = new MemoryStream ();
var w = new BinaryStreamWriter (data);
w.WriteByte (0x4d);
w.WriteByte (0x50);
w.WriteByte (0x44);
w.WriteByte (0x42);
w.WriteInt32 ((int) stream.Length);
stream.Position = 0;
using (var compress_stream = new DeflateStream (data, CompressionMode.Compress, leaveOpen: true))
stream.CopyTo (compress_stream);
directory.SizeOfData = (int) data.Length;
return new ImageDebugHeader (new [] {
writer.GetDebugHeader ().Entries [0],
new ImageDebugHeaderEntry (directory, data.ToArray ())
});
}
public void Write (MethodDebugInformation info)
{
writer.Write (info);
}
public void Dispose ()
{
}
void IMetadataSymbolWriter.SetMetadata (MetadataBuilder metadata)
{
((IMetadataSymbolWriter) writer).SetMetadata (metadata);
}
void IMetadataSymbolWriter.WriteModule ()
{
((IMetadataSymbolWriter) writer).WriteModule ();
}
}
#endif
static class PdbGuidMapping {
static readonly Dictionary<Guid, DocumentLanguage> guid_language = new Dictionary<Guid, DocumentLanguage> ();
static readonly Dictionary<DocumentLanguage, Guid> language_guid = new Dictionary<DocumentLanguage, Guid> ();
static PdbGuidMapping ()
{
AddMapping (DocumentLanguage.C, new Guid ("63a08714-fc37-11d2-904c-00c04fa302a1"));
AddMapping (DocumentLanguage.Cpp, new Guid ("3a12d0b7-c26c-11d0-b442-00a0244a1dd2"));
AddMapping (DocumentLanguage.CSharp, new Guid ("3f5162f8-07c6-11d3-9053-00c04fa302a1"));
AddMapping (DocumentLanguage.Basic, new Guid ("3a12d0b8-c26c-11d0-b442-00a0244a1dd2"));
AddMapping (DocumentLanguage.Java, new Guid ("3a12d0b4-c26c-11d0-b442-00a0244a1dd2"));
AddMapping (DocumentLanguage.Cobol, new Guid ("af046cd1-d0e1-11d2-977c-00a0c9b4d50c"));
AddMapping (DocumentLanguage.Pascal, new Guid ("af046cd2-d0e1-11d2-977c-00a0c9b4d50c"));
AddMapping (DocumentLanguage.Cil, new Guid ("af046cd3-d0e1-11d2-977c-00a0c9b4d50c"));
AddMapping (DocumentLanguage.JScript, new Guid ("3a12d0b6-c26c-11d0-b442-00a0244a1dd2"));
AddMapping (DocumentLanguage.Smc, new Guid ("0d9b9f7b-6611-11d3-bd2a-0000f80849bd"));
AddMapping (DocumentLanguage.MCpp, new Guid ("4b35fde8-07c6-11d3-9053-00c04fa302a1"));
AddMapping (DocumentLanguage.FSharp, new Guid ("ab4f38c9-b6e6-43ba-be3b-58080b2ccce3"));
}
static void AddMapping (DocumentLanguage language, Guid guid)
{
guid_language.Add (guid, language);
language_guid.Add (language, guid);
}
static readonly Guid type_text = new Guid ("5a869d0b-6611-11d3-bd2a-0000f80849bd");
public static DocumentType ToType (this Guid guid)
{
if (guid == type_text)
return DocumentType.Text;
return DocumentType.Other;
}
public static Guid ToGuid (this DocumentType type)
{
if (type == DocumentType.Text)
return type_text;
return new Guid ();
}
static readonly Guid hash_md5 = new Guid ("406ea660-64cf-4c82-b6f0-42d48172a799");
static readonly Guid hash_sha1 = new Guid ("ff1816ec-aa5e-4d10-87f7-6f4963833460");
static readonly Guid hash_sha256 = new Guid ("8829d00f-11b8-4213-878b-770e8597ac16");
public static DocumentHashAlgorithm ToHashAlgorithm (this Guid guid)
{
if (guid == hash_md5)
return DocumentHashAlgorithm.MD5;
if (guid == hash_sha1)
return DocumentHashAlgorithm.SHA1;
if (guid == hash_sha256)
return DocumentHashAlgorithm.SHA256;
return DocumentHashAlgorithm.None;
}
public static Guid ToGuid (this DocumentHashAlgorithm hash_algo)
{
if (hash_algo == DocumentHashAlgorithm.MD5)
return hash_md5;
if (hash_algo == DocumentHashAlgorithm.SHA1)
return hash_sha1;
if (hash_algo == DocumentHashAlgorithm.SHA256)
return hash_sha256;
return new Guid ();
}
public static DocumentLanguage ToLanguage (this Guid guid)
{
DocumentLanguage language;
if (!guid_language.TryGetValue (guid, out language))
return DocumentLanguage.Other;
return language;
}
public static Guid ToGuid (this DocumentLanguage language)
{
Guid guid;
if (!language_guid.TryGetValue (language, out guid))
return new Guid ();
return guid;
}
static readonly Guid vendor_ms = new Guid ("994b45c4-e6e9-11d2-903f-00c04fa302a1");
public static DocumentLanguageVendor ToVendor (this Guid guid)
{
if (guid == vendor_ms)
return DocumentLanguageVendor.Microsoft;
return DocumentLanguageVendor.Other;
}
public static Guid ToGuid (this DocumentLanguageVendor vendor)
{
if (vendor == DocumentLanguageVendor.Microsoft)
return vendor_ms;
return new Guid ();
}
}
}
}
#endregion
#region Mono.Cecil.Cil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil.Cil {
internal sealed class SequencePoint {
internal InstructionOffset offset;
Document document;
int start_line;
int start_column;
int end_line;
int end_column;
public int Offset {
get { return offset.Offset; }
}
public int StartLine {
get { return start_line; }
set { start_line = value; }
}
public int StartColumn {
get { return start_column; }
set { start_column = value; }
}
public int EndLine {
get { return end_line; }
set { end_line = value; }
}
public int EndColumn {
get { return end_column; }
set { end_column = value; }
}
public bool IsHidden {
get { return start_line == 0xfeefee && start_line == end_line; }
}
public Document Document {
get { return document; }
set { document = value; }
}
internal SequencePoint (int offset, Document document)
{
if (document == null)
throw new ArgumentNullException ("document");
this.offset = new InstructionOffset (offset);
this.document = document;
}
public SequencePoint (Instruction instruction, Document document)
{
if (document == null)
throw new ArgumentNullException ("document");
this.offset = new InstructionOffset (instruction);
this.document = document;
}
}
}
}
#endregion
#region Mono.Cecil.Cil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using SR = System.Reflection;
using Mono.Collections.Generic;
using Mono.Cecil.Cil;
using Mono.Cecil.PE;
namespace Mono.Cecil.Cil {
[StructLayout (LayoutKind.Sequential)]
internal struct ImageDebugDirectory {
public const int Size = 28;
public int Characteristics;
public int TimeDateStamp;
public short MajorVersion;
public short MinorVersion;
public ImageDebugType Type;
public int SizeOfData;
public int AddressOfRawData;
public int PointerToRawData;
}
internal enum ImageDebugType {
CodeView = 2,
Deterministic = 16,
EmbeddedPortablePdb = 17,
}
internal sealed class ImageDebugHeader {
readonly ImageDebugHeaderEntry [] entries;
public bool HasEntries {
get { return !entries.IsNullOrEmpty (); }
}
public ImageDebugHeaderEntry [] Entries {
get { return entries; }
}
public ImageDebugHeader (ImageDebugHeaderEntry [] entries)
{
this.entries = entries ?? Empty<ImageDebugHeaderEntry>.Array;
}
public ImageDebugHeader ()
: this (Empty<ImageDebugHeaderEntry>.Array)
{
}
public ImageDebugHeader (ImageDebugHeaderEntry entry)
: this (new [] { entry })
{
}
}
internal sealed class ImageDebugHeaderEntry {
ImageDebugDirectory directory;
readonly byte [] data;
public ImageDebugDirectory Directory {
get { return directory; }
internal set { directory = value; }
}
public byte [] Data {
get { return data; }
}
public ImageDebugHeaderEntry (ImageDebugDirectory directory, byte [] data)
{
this.directory = directory;
this.data = data ?? Empty<byte>.Array;
}
}
internal sealed class ScopeDebugInformation : DebugInformation {
internal InstructionOffset start;
internal InstructionOffset end;
internal ImportDebugInformation import;
internal Collection<ScopeDebugInformation> scopes;
internal Collection<VariableDebugInformation> variables;
internal Collection<ConstantDebugInformation> constants;
public InstructionOffset Start {
get { return start; }
set { start = value; }
}
public InstructionOffset End {
get { return end; }
set { end = value; }
}
public ImportDebugInformation Import {
get { return import; }
set { import = value; }
}
public bool HasScopes {
get { return !scopes.IsNullOrEmpty (); }
}
public Collection<ScopeDebugInformation> Scopes {
get { return scopes ?? (scopes = new Collection<ScopeDebugInformation> ()); }
}
public bool HasVariables {
get { return !variables.IsNullOrEmpty (); }
}
public Collection<VariableDebugInformation> Variables {
get { return variables ?? (variables = new Collection<VariableDebugInformation> ()); }
}
public bool HasConstants {
get { return !constants.IsNullOrEmpty (); }
}
public Collection<ConstantDebugInformation> Constants {
get { return constants ?? (constants = new Collection<ConstantDebugInformation> ()); }
}
internal ScopeDebugInformation ()
{
this.token = new MetadataToken (TokenType.LocalScope);
}
public ScopeDebugInformation (Instruction start, Instruction end)
: this ()
{
if (start == null)
throw new ArgumentNullException ("start");
this.start = new InstructionOffset (start);
if (end != null)
this.end = new InstructionOffset (end);
}
public bool TryGetName (VariableDefinition variable, out string name)
{
name = null;
if (variables == null || variables.Count == 0)
return false;
for (int i = 0; i < variables.Count; i++) {
if (variables [i].Index == variable.Index) {
name = variables [i].Name;
return true;
}
}
return false;
}
}
internal struct InstructionOffset {
readonly Instruction instruction;
readonly int? offset;
public int Offset {
get {
if (instruction != null)
return instruction.Offset;
if (offset.HasValue)
return offset.Value;
throw new NotSupportedException ();
}
}
public bool IsEndOfMethod {
get { return instruction == null && !offset.HasValue; }
}
public InstructionOffset (Instruction instruction)
{
if (instruction == null)
throw new ArgumentNullException ("instruction");
this.instruction = instruction;
this.offset = null;
}
public InstructionOffset (int offset)
{
this.instruction = null;
this.offset = offset;
}
}
[Flags]
internal enum VariableAttributes : ushort {
None = 0,
DebuggerHidden = 1,
}
internal struct VariableIndex {
readonly VariableDefinition variable;
readonly int? index;
public int Index {
get {
if (variable != null)
return variable.Index;
if (index.HasValue)
return index.Value;
throw new NotSupportedException ();
}
}
public VariableIndex (VariableDefinition variable)
{
if (variable == null)
throw new ArgumentNullException ("variable");
this.variable = variable;
this.index = null;
}
public VariableIndex (int index)
{
this.variable = null;
this.index = index;
}
}
internal abstract class DebugInformation : ICustomDebugInformationProvider {
internal MetadataToken token;
internal Collection<CustomDebugInformation> custom_infos;
public MetadataToken MetadataToken {
get { return token; }
set { token = value; }
}
public bool HasCustomDebugInformations {
get { return !custom_infos.IsNullOrEmpty (); }
}
public Collection<CustomDebugInformation> CustomDebugInformations {
get { return custom_infos ?? (custom_infos = new Collection<CustomDebugInformation> ()); }
}
internal DebugInformation ()
{
}
}
internal sealed class VariableDebugInformation : DebugInformation {
string name;
ushort attributes;
internal VariableIndex index;
public int Index {
get { return index.Index; }
}
public string Name {
get { return name; }
set { name = value; }
}
public VariableAttributes Attributes {
get { return (VariableAttributes) attributes; }
set { attributes = (ushort) value; }
}
public bool IsDebuggerHidden {
get { return attributes.GetAttributes ((ushort) VariableAttributes.DebuggerHidden); }
set { attributes = attributes.SetAttributes ((ushort) VariableAttributes.DebuggerHidden, value); }
}
internal VariableDebugInformation (int index, string name)
{
if (name == null)
throw new ArgumentNullException ("name");
this.index = new VariableIndex (index);
this.name = name;
}
public VariableDebugInformation (VariableDefinition variable, string name)
{
if (variable == null)
throw new ArgumentNullException ("variable");
if (name == null)
throw new ArgumentNullException ("name");
this.index = new VariableIndex (variable);
this.name = name;
this.token = new MetadataToken (TokenType.LocalVariable);
}
}
internal sealed class ConstantDebugInformation : DebugInformation {
string name;
TypeReference constant_type;
object value;
public string Name {
get { return name; }
set { name = value; }
}
public TypeReference ConstantType {
get { return constant_type; }
set { constant_type = value; }
}
public object Value {
get { return value; }
set { this.value = value; }
}
public ConstantDebugInformation (string name, TypeReference constant_type, object value)
{
if (name == null)
throw new ArgumentNullException ("name");
this.name = name;
this.constant_type = constant_type;
this.value = value;
this.token = new MetadataToken (TokenType.LocalConstant);
}
}
internal enum ImportTargetKind : byte {
ImportNamespace = 1,
ImportNamespaceInAssembly = 2,
ImportType = 3,
ImportXmlNamespaceWithAlias = 4,
ImportAlias = 5,
DefineAssemblyAlias = 6,
DefineNamespaceAlias = 7,
DefineNamespaceInAssemblyAlias = 8,
DefineTypeAlias = 9,
}
internal sealed class ImportTarget {
internal ImportTargetKind kind;
internal string @namespace;
internal TypeReference type;
internal AssemblyNameReference reference;
internal string alias;
public string Namespace {
get { return @namespace; }
set { @namespace = value; }
}
public TypeReference Type {
get { return type; }
set { type = value; }
}
public AssemblyNameReference AssemblyReference {
get { return reference; }
set { reference = value; }
}
public string Alias {
get { return alias; }
set { alias = value; }
}
public ImportTargetKind Kind {
get { return kind; }
set { kind = value; }
}
public ImportTarget (ImportTargetKind kind)
{
this.kind = kind;
}
}
internal sealed class ImportDebugInformation : DebugInformation {
internal ImportDebugInformation parent;
internal Collection<ImportTarget> targets;
public bool HasTargets {
get { return !targets.IsNullOrEmpty (); }
}
public Collection<ImportTarget> Targets {
get { return targets ?? (targets = new Collection<ImportTarget> ()); }
}
public ImportDebugInformation Parent {
get { return parent; }
set { parent = value; }
}
public ImportDebugInformation ()
{
this.token = new MetadataToken (TokenType.ImportScope);
}
}
internal interface ICustomDebugInformationProvider : IMetadataTokenProvider {
bool HasCustomDebugInformations { get; }
Collection<CustomDebugInformation> CustomDebugInformations { get; }
}
internal enum CustomDebugInformationKind {
Binary,
StateMachineScope,
DynamicVariable,
DefaultNamespace,
AsyncMethodBody,
EmbeddedSource,
SourceLink,
}
internal abstract class CustomDebugInformation : DebugInformation {
Guid identifier;
public Guid Identifier {
get { return identifier; }
}
public abstract CustomDebugInformationKind Kind { get; }
internal CustomDebugInformation (Guid identifier)
{
this.identifier = identifier;
this.token = new MetadataToken (TokenType.CustomDebugInformation);
}
}
internal sealed class BinaryCustomDebugInformation : CustomDebugInformation {
byte [] data;
public byte [] Data {
get { return data; }
set { data = value; }
}
public override CustomDebugInformationKind Kind {
get { return CustomDebugInformationKind.Binary; }
}
public BinaryCustomDebugInformation (Guid identifier, byte [] data)
: base (identifier)
{
this.data = data;
}
}
internal sealed class AsyncMethodBodyDebugInformation : CustomDebugInformation {
internal InstructionOffset catch_handler;
internal Collection<InstructionOffset> yields;
internal Collection<InstructionOffset> resumes;
internal Collection<MethodDefinition> resume_methods;
public InstructionOffset CatchHandler {
get { return catch_handler; }
set { catch_handler = value; }
}
public Collection<InstructionOffset> Yields {
get { return yields ?? (yields = new Collection<InstructionOffset> ()); }
}
public Collection<InstructionOffset> Resumes {
get { return resumes ?? (resumes = new Collection<InstructionOffset> ()); }
}
public Collection<MethodDefinition> ResumeMethods {
get { return resume_methods ?? (resume_methods = new Collection<MethodDefinition> ()); }
}
public override CustomDebugInformationKind Kind {
get { return CustomDebugInformationKind.AsyncMethodBody; }
}
public static Guid KindIdentifier = new Guid ("{54FD2AC5-E925-401A-9C2A-F94F171072F8}");
internal AsyncMethodBodyDebugInformation (int catchHandler)
: base (KindIdentifier)
{
this.catch_handler = new InstructionOffset (catchHandler);
}
public AsyncMethodBodyDebugInformation (Instruction catchHandler)
: base (KindIdentifier)
{
this.catch_handler = new InstructionOffset (catchHandler);
}
public AsyncMethodBodyDebugInformation ()
: base (KindIdentifier)
{
this.catch_handler = new InstructionOffset (-1);
}
}
internal sealed class StateMachineScope {
internal InstructionOffset start;
internal InstructionOffset end;
public InstructionOffset Start {
get { return start; }
set { start = value; }
}
public InstructionOffset End {
get { return end; }
set { end = value; }
}
internal StateMachineScope (int start, int end)
{
this.start = new InstructionOffset (start);
this.end = new InstructionOffset (end);
}
public StateMachineScope (Instruction start, Instruction end)
{
this.start = new InstructionOffset (start);
this.end = end != null ? new InstructionOffset (end) : new InstructionOffset ();
}
}
internal sealed class StateMachineScopeDebugInformation : CustomDebugInformation {
internal Collection<StateMachineScope> scopes;
public Collection<StateMachineScope> Scopes {
get { return scopes ?? (scopes = new Collection<StateMachineScope> ()); }
}
public override CustomDebugInformationKind Kind {
get { return CustomDebugInformationKind.StateMachineScope; }
}
public static Guid KindIdentifier = new Guid ("{6DA9A61E-F8C7-4874-BE62-68BC5630DF71}");
public StateMachineScopeDebugInformation ()
: base (KindIdentifier)
{
}
}
internal sealed class EmbeddedSourceDebugInformation : CustomDebugInformation {
internal byte [] content;
internal bool compress;
public byte [] Content {
get { return content; }
set { content = value; }
}
public bool Compress {
get { return compress; }
set { compress = value; }
}
public override CustomDebugInformationKind Kind {
get { return CustomDebugInformationKind.EmbeddedSource; }
}
public static Guid KindIdentifier = new Guid ("{0E8A571B-6926-466E-B4AD-8AB04611F5FE}");
public EmbeddedSourceDebugInformation (byte [] content, bool compress)
: base (KindIdentifier)
{
this.content = content;
this.compress = compress;
}
}
internal sealed class SourceLinkDebugInformation : CustomDebugInformation {
internal string content;
public string Content {
get { return content; }
set { content = value; }
}
public override CustomDebugInformationKind Kind {
get { return CustomDebugInformationKind.SourceLink; }
}
public static Guid KindIdentifier = new Guid ("{CC110556-A091-4D38-9FEC-25AB9A351A6A}");
public SourceLinkDebugInformation (string content)
: base (KindIdentifier)
{
this.content = content;
}
}
internal sealed class MethodDebugInformation : DebugInformation {
internal MethodDefinition method;
internal Collection<SequencePoint> sequence_points;
internal ScopeDebugInformation scope;
internal MethodDefinition kickoff_method;
internal int code_size;
internal MetadataToken local_var_token;
public MethodDefinition Method {
get { return method; }
}
public bool HasSequencePoints {
get { return !sequence_points.IsNullOrEmpty (); }
}
public Collection<SequencePoint> SequencePoints {
get { return sequence_points ?? (sequence_points = new Collection<SequencePoint> ()); }
}
public ScopeDebugInformation Scope {
get { return scope; }
set { scope = value; }
}
public MethodDefinition StateMachineKickOffMethod {
get { return kickoff_method; }
set { kickoff_method = value; }
}
internal MethodDebugInformation (MethodDefinition method)
{
if (method == null)
throw new ArgumentNullException ("method");
this.method = method;
this.token = new MetadataToken (TokenType.MethodDebugInformation, method.MetadataToken.RID);
}
public SequencePoint GetSequencePoint (Instruction instruction)
{
if (!HasSequencePoints)
return null;
for (int i = 0; i < sequence_points.Count; i++)
if (sequence_points [i].Offset == instruction.Offset)
return sequence_points [i];
return null;
}
public IDictionary<Instruction, SequencePoint> GetSequencePointMapping ()
{
var instruction_mapping = new Dictionary<Instruction, SequencePoint> ();
if (!HasSequencePoints || !method.HasBody)
return instruction_mapping;
var offset_mapping = new Dictionary<int, SequencePoint> (sequence_points.Count);
for (int i = 0; i < sequence_points.Count; i++) {
if (!offset_mapping.ContainsKey (sequence_points [i].Offset))
offset_mapping.Add (sequence_points [i].Offset, sequence_points [i]);
}
var instructions = method.Body.Instructions;
for (int i = 0; i < instructions.Count; i++) {
SequencePoint sequence_point;
if (offset_mapping.TryGetValue (instructions [i].Offset, out sequence_point))
instruction_mapping.Add (instructions [i], sequence_point);
}
return instruction_mapping;
}
public IEnumerable<ScopeDebugInformation> GetScopes ()
{
if (scope == null)
return Empty<ScopeDebugInformation>.Array;
return GetScopes (new[] { scope });
}
static IEnumerable<ScopeDebugInformation> GetScopes (IList<ScopeDebugInformation> scopes)
{
for (int i = 0; i < scopes.Count; i++) {
var scope = scopes [i];
yield return scope;
if (!scope.HasScopes)
continue;
foreach (var sub_scope in GetScopes (scope.Scopes))
yield return sub_scope;
}
}
public bool TryGetName (VariableDefinition variable, out string name)
{
name = null;
var has_name = false;
var unique_name = "";
foreach (var scope in GetScopes ()) {
string slot_name;
if (!scope.TryGetName (variable, out slot_name))
continue;
if (!has_name) {
has_name = true;
unique_name = slot_name;
continue;
}
if (unique_name != slot_name)
return false;
}
name = unique_name;
return has_name;
}
}
internal interface ISymbolReader : IDisposable {
#if !READ_ONLY
ISymbolWriterProvider GetWriterProvider ();
#endif
bool ProcessDebugHeader (ImageDebugHeader header);
MethodDebugInformation Read (MethodDefinition method);
}
internal interface ISymbolReaderProvider {
ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName);
ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream);
}
#if !NET_CORE
[Serializable]
#endif
internal sealed class SymbolsNotFoundException : FileNotFoundException {
public SymbolsNotFoundException (string message) : base (message)
{
}
#if !NET_CORE
SymbolsNotFoundException (
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base (info, context)
{
}
#endif
}
#if !NET_CORE
[Serializable]
#endif
internal sealed class SymbolsNotMatchingException : InvalidOperationException {
public SymbolsNotMatchingException (string message) : base (message)
{
}
#if !NET_CORE
SymbolsNotMatchingException (
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base (info, context)
{
}
#endif
}
internal class DefaultSymbolReaderProvider : ISymbolReaderProvider {
readonly bool throw_if_no_symbol;
public DefaultSymbolReaderProvider ()
: this (throwIfNoSymbol: true)
{
}
public DefaultSymbolReaderProvider (bool throwIfNoSymbol)
{
throw_if_no_symbol = throwIfNoSymbol;
}
public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName)
{
if (module.Image.HasDebugTables ())
return null;
if (module.HasDebugHeader) {
var header = module.GetDebugHeader ();
var entry = header.GetEmbeddedPortablePdbEntry ();
if (entry != null)
return new EmbeddedPortablePdbReaderProvider ().GetSymbolReader (module, fileName);
}
var pdb_file_name = Mixin.GetPdbFileName (fileName);
if (File.Exists (pdb_file_name)) {
if (Mixin.IsPortablePdb (Mixin.GetPdbFileName (fileName)))
return new PortablePdbReaderProvider ().GetSymbolReader (module, fileName);
try {
return SymbolProvider.GetReaderProvider (SymbolKind.NativePdb).GetSymbolReader (module, fileName);
} catch (Exception) {
// We might not include support for native pdbs.
}
}
var mdb_file_name = Mixin.GetMdbFileName (fileName);
if (File.Exists (mdb_file_name)) {
try {
return SymbolProvider.GetReaderProvider (SymbolKind.Mdb).GetSymbolReader (module, fileName);
} catch (Exception) {
// We might not include support for mdbs.
}
}
if (throw_if_no_symbol)
throw new SymbolsNotFoundException (string.Format ("No symbol found for file: {0}", fileName));
return null;
}
public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream)
{
if (module.Image.HasDebugTables ())
return null;
if (module.HasDebugHeader) {
var header = module.GetDebugHeader ();
var entry = header.GetEmbeddedPortablePdbEntry ();
if (entry != null)
return new EmbeddedPortablePdbReaderProvider ().GetSymbolReader (module, "");
}
Mixin.CheckStream (symbolStream);
Mixin.CheckReadSeek (symbolStream);
var position = symbolStream.Position;
const int portablePdbHeader = 0x424a5342;
var reader = new BinaryStreamReader (symbolStream);
var intHeader = reader.ReadInt32 ();
symbolStream.Position = position;
if (intHeader == portablePdbHeader) {
return new PortablePdbReaderProvider ().GetSymbolReader (module, symbolStream);
}
const string nativePdbHeader = "Microsoft C/C++ MSF 7.00";
var bytesHeader = reader.ReadBytes (nativePdbHeader.Length);
symbolStream.Position = position;
var isNativePdb = true;
for (var i = 0; i < bytesHeader.Length; i++) {
if (bytesHeader [i] != (byte) nativePdbHeader [i]) {
isNativePdb = false;
break;
}
}
if (isNativePdb) {
try {
return SymbolProvider.GetReaderProvider (SymbolKind.NativePdb).GetSymbolReader (module, symbolStream);
} catch (Exception) {
// We might not include support for native pdbs.
}
}
const long mdbHeader = 0x45e82623fd7fa614;
var longHeader = reader.ReadInt64 ();
symbolStream.Position = position;
if (longHeader == mdbHeader) {
try {
return SymbolProvider.GetReaderProvider (SymbolKind.Mdb).GetSymbolReader (module, symbolStream);
} catch (Exception) {
// We might not include support for mdbs.
}
}
if (throw_if_no_symbol)
throw new SymbolsNotFoundException (string.Format ("No symbols found in stream"));
return null;
}
}
enum SymbolKind {
NativePdb,
PortablePdb,
EmbeddedPortablePdb,
Mdb,
}
static class SymbolProvider {
static SR.AssemblyName GetSymbolAssemblyName (SymbolKind kind)
{
if (kind == SymbolKind.PortablePdb)
throw new ArgumentException ();
var suffix = GetSymbolNamespace (kind);
var cecil_name = typeof (SymbolProvider).Assembly ().GetName ();
var name = new SR.AssemblyName {
Name = cecil_name.Name + "." + suffix,
Version = cecil_name.Version,
};
name.SetPublicKeyToken (cecil_name.GetPublicKeyToken ());
return name;
}
static Type GetSymbolType (SymbolKind kind, string fullname)
{
var type = Type.GetType (fullname);
if (type != null)
return type;
var assembly_name = GetSymbolAssemblyName (kind);
type = Type.GetType (fullname + ", " + assembly_name.FullName);
if (type != null)
return type;
try {
var assembly = SR.Assembly.Load (assembly_name);
if (assembly != null)
return assembly.GetType (fullname);
} catch (FileNotFoundException) {
} catch (FileLoadException) {
}
return null;
}
public static ISymbolReaderProvider GetReaderProvider (SymbolKind kind)
{
if (kind == SymbolKind.PortablePdb)
return new PortablePdbReaderProvider ();
if (kind == SymbolKind.EmbeddedPortablePdb)
return new EmbeddedPortablePdbReaderProvider ();
var provider_name = GetSymbolTypeName (kind, "ReaderProvider");
var type = GetSymbolType (kind, provider_name);
if (type == null)
throw new TypeLoadException ("Could not find symbol provider type " + provider_name);
return (ISymbolReaderProvider) Activator.CreateInstance (type);
}
static string GetSymbolTypeName (SymbolKind kind, string name)
{
return "Mono.Cecil" + "." + GetSymbolNamespace (kind) + "." + kind + name;
}
static string GetSymbolNamespace (SymbolKind kind)
{
if (kind == SymbolKind.PortablePdb || kind == SymbolKind.EmbeddedPortablePdb)
return "Cil";
if (kind == SymbolKind.NativePdb)
return "Pdb";
if (kind == SymbolKind.Mdb)
return "Mdb";
throw new ArgumentException ();
}
}
#if !READ_ONLY
internal interface ISymbolWriter : IDisposable {
ISymbolReaderProvider GetReaderProvider ();
ImageDebugHeader GetDebugHeader ();
void Write (MethodDebugInformation info);
}
internal interface ISymbolWriterProvider {
ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName);
ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream);
}
internal class DefaultSymbolWriterProvider : ISymbolWriterProvider {
public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName)
{
var reader = module.SymbolReader;
if (reader == null)
throw new InvalidOperationException ();
if (module.Image != null && module.Image.HasDebugTables ())
return null;
return reader.GetWriterProvider ().GetSymbolWriter (module, fileName);
}
public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream)
{
throw new NotSupportedException ();
}
}
#endif
}
namespace Mono.Cecil {
static partial class Mixin {
public static ImageDebugHeaderEntry GetCodeViewEntry (this ImageDebugHeader header)
{
return GetEntry (header, ImageDebugType.CodeView);
}
public static ImageDebugHeaderEntry GetDeterministicEntry (this ImageDebugHeader header)
{
return GetEntry (header, ImageDebugType.Deterministic);
}
public static ImageDebugHeader AddDeterministicEntry (this ImageDebugHeader header)
{
var entry = new ImageDebugHeaderEntry (new ImageDebugDirectory { Type = ImageDebugType.Deterministic }, Empty<byte>.Array);
if (header == null)
return new ImageDebugHeader (entry);
var entries = new ImageDebugHeaderEntry [header.Entries.Length + 1];
Array.Copy (header.Entries, entries, header.Entries.Length);
entries [entries.Length - 1] = entry;
return new ImageDebugHeader (entries);
}
public static ImageDebugHeaderEntry GetEmbeddedPortablePdbEntry (this ImageDebugHeader header)
{
return GetEntry (header, ImageDebugType.EmbeddedPortablePdb);
}
private static ImageDebugHeaderEntry GetEntry (this ImageDebugHeader header, ImageDebugType type)
{
if (!header.HasEntries)
return null;
for (var i = 0; i < header.Entries.Length; i++) {
var entry = header.Entries [i];
if (entry.Directory.Type == type)
return entry;
}
return null;
}
public static string GetPdbFileName (string assemblyFileName)
{
return Path.ChangeExtension (assemblyFileName, ".pdb");
}
public static string GetMdbFileName (string assemblyFileName)
{
return assemblyFileName + ".mdb";
}
public static bool IsPortablePdb (string fileName)
{
using (var file = new FileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
return IsPortablePdb (file);
}
public static bool IsPortablePdb (Stream stream)
{
const uint ppdb_signature = 0x424a5342;
if (stream.Length < 4) return false;
var position = stream.Position;
try {
var reader = new BinaryReader (stream);
return reader.ReadUInt32 () == ppdb_signature;
} finally {
stream.Position = position;
}
}
}
}
}
#endregion
#region Mono.Cecil.Cil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil.Cil {
internal sealed class VariableDefinition : VariableReference {
public bool IsPinned {
get { return variable_type.IsPinned; }
}
public VariableDefinition (TypeReference variableType)
: base (variableType)
{
}
public override VariableDefinition Resolve ()
{
return this;
}
}
}
}
#endregion
#region Mono.Cecil.Cil\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil.Cil {
internal abstract class VariableReference {
internal int index = -1;
protected TypeReference variable_type;
public TypeReference VariableType {
get { return variable_type; }
set { variable_type = value; }
}
public int Index {
get { return index; }
}
internal VariableReference (TypeReference variable_type)
{
this.variable_type = variable_type;
}
public abstract VariableDefinition Resolve ();
public override string ToString ()
{
if (index >= 0)
return "V_" + index;
return string.Empty;
}
}
}
}
#endregion
#region Mono.Cecil.Metadata\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil.Metadata {
sealed class BlobHeap : Heap {
public BlobHeap (byte [] data)
: base (data)
{
}
public byte [] Read (uint index)
{
if (index == 0 || index > this.data.Length - 1)
return Empty<byte>.Array;
int position = (int) index;
int length = (int) data.ReadCompressedUInt32 (ref position);
if (length > data.Length - position)
return Empty<byte>.Array;
var buffer = new byte [length];
Buffer.BlockCopy (data, position, buffer, 0, length);
return buffer;
}
public void GetView (uint signature, out byte [] buffer, out int index, out int length)
{
if (signature == 0 || signature > data.Length - 1) {
buffer = null;
index = length = 0;
return;
}
buffer = data;
index = (int) signature;
length = (int) buffer.ReadCompressedUInt32 (ref index);
}
}
}
}
#endregion
#region Mono.Cecil.Metadata\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Collections.Generic;
using System.Text;
using Mono.Cecil.PE;
using RVA = System.UInt32;
#if !READ_ONLY
namespace Mono.Cecil.Metadata {
sealed class TableHeapBuffer : HeapBuffer {
readonly ModuleDefinition module;
readonly MetadataBuilder metadata;
readonly internal TableInformation [] table_infos = new TableInformation [Mixin.TableCount];
readonly internal MetadataTable [] tables = new MetadataTable [Mixin.TableCount];
bool large_string;
bool large_blob;
bool large_guid;
readonly int [] coded_index_sizes = new int [Mixin.CodedIndexCount];
readonly Func<Table, int> counter;
internal uint [] string_offsets;
public override bool IsEmpty {
get { return false; }
}
public TableHeapBuffer (ModuleDefinition module, MetadataBuilder metadata)
: base (24)
{
this.module = module;
this.metadata = metadata;
this.counter = GetTableLength;
}
int GetTableLength (Table table)
{
return (int) table_infos [(int) table].Length;
}
public TTable GetTable<TTable> (Table table) where TTable : MetadataTable, new ()
{
var md_table = (TTable) tables [(int) table];
if (md_table != null)
return md_table;
md_table = new TTable ();
tables [(int) table] = md_table;
return md_table;
}
public void WriteBySize (uint value, int size)
{
if (size == 4)
WriteUInt32 (value);
else
WriteUInt16 ((ushort) value);
}
public void WriteBySize (uint value, bool large)
{
if (large)
WriteUInt32 (value);
else
WriteUInt16 ((ushort) value);
}
public void WriteString (uint @string)
{
WriteBySize (string_offsets [@string], large_string);
}
public void WriteBlob (uint blob)
{
WriteBySize (blob, large_blob);
}
public void WriteGuid (uint guid)
{
WriteBySize (guid, large_guid);
}
public void WriteRID (uint rid, Table table)
{
WriteBySize (rid, table_infos [(int) table].IsLarge);
}
int GetCodedIndexSize (CodedIndex coded_index)
{
var index = (int) coded_index;
var size = coded_index_sizes [index];
if (size != 0)
return size;
return coded_index_sizes [index] = coded_index.GetSize (counter);
}
public void WriteCodedRID (uint rid, CodedIndex coded_index)
{
WriteBySize (rid, GetCodedIndexSize (coded_index));
}
public void WriteTableHeap ()
{
WriteUInt32 (0); // Reserved
WriteByte (GetTableHeapVersion ()); // MajorVersion
WriteByte (0); // MinorVersion
WriteByte (GetHeapSizes ()); // HeapSizes
WriteByte (10); // Reserved2
WriteUInt64 (GetValid ()); // Valid
WriteUInt64 (0xc416003301fa00); // Sorted
WriteRowCount ();
WriteTables ();
}
void WriteRowCount ()
{
for (int i = 0; i < tables.Length; i++) {
var table = tables [i];
if (table == null || table.Length == 0)
continue;
WriteUInt32 ((uint) table.Length);
}
}
void WriteTables ()
{
for (int i = 0; i < tables.Length; i++) {
var table = tables [i];
if (table == null || table.Length == 0)
continue;
table.Write (this);
}
}
ulong GetValid ()
{
ulong valid = 0;
for (int i = 0; i < tables.Length; i++) {
var table = tables [i];
if (table == null || table.Length == 0)
continue;
table.Sort ();
valid |= (1UL << i);
}
return valid;
}
public void ComputeTableInformations ()
{
if (metadata.metadata_builder != null)
ComputeTableInformations (metadata.metadata_builder.table_heap);
ComputeTableInformations (metadata.table_heap);
}
void ComputeTableInformations (TableHeapBuffer table_heap)
{
var tables = table_heap.tables;
for (int i = 0; i < tables.Length; i++) {
var table = tables [i];
if (table != null && table.Length > 0)
table_infos [i].Length = (uint) table.Length;
}
}
byte GetHeapSizes ()
{
byte heap_sizes = 0;
if (metadata.string_heap.IsLarge) {
large_string = true;
heap_sizes |= 0x01;
}
if (metadata.guid_heap.IsLarge) {
large_guid = true;
heap_sizes |= 0x02;
}
if (metadata.blob_heap.IsLarge) {
large_blob = true;
heap_sizes |= 0x04;
}
return heap_sizes;
}
byte GetTableHeapVersion ()
{
switch (module.Runtime) {
case TargetRuntime.Net_1_0:
case TargetRuntime.Net_1_1:
return 1;
default:
return 2;
}
}
public void FixupData (RVA data_rva)
{
var table = GetTable<FieldRVATable> (Table.FieldRVA);
if (table.length == 0)
return;
var field_idx_size = GetTable<FieldTable> (Table.Field).IsLarge ? 4 : 2;
var previous = this.position;
base.position = table.position;
for (int i = 0; i < table.length; i++) {
var rva = ReadUInt32 ();
base.position -= 4;
WriteUInt32 (rva + data_rva);
base.position += field_idx_size;
}
base.position = previous;
}
}
sealed class ResourceBuffer : ByteBuffer {
public ResourceBuffer ()
: base (0)
{
}
public uint AddResource (byte [] resource)
{
var offset = (uint) this.position;
WriteInt32 (resource.Length);
WriteBytes (resource);
return offset;
}
}
sealed class DataBuffer : ByteBuffer {
public DataBuffer ()
: base (0)
{
}
public RVA AddData (byte [] data)
{
var rva = (RVA) position;
WriteBytes (data);
return rva;
}
}
abstract class HeapBuffer : ByteBuffer {
public bool IsLarge {
get { return base.length > 65535; }
}
public abstract bool IsEmpty { get; }
protected HeapBuffer (int length)
: base (length)
{
}
}
sealed class GuidHeapBuffer : HeapBuffer {
readonly Dictionary<Guid, uint> guids = new Dictionary<Guid, uint> ();
public override bool IsEmpty {
get { return length == 0; }
}
public GuidHeapBuffer ()
: base (16)
{
}
public uint GetGuidIndex (Guid guid)
{
uint index;
if (guids.TryGetValue (guid, out index))
return index;
index = (uint) guids.Count + 1;
WriteGuid (guid);
guids.Add (guid, index);
return index;
}
void WriteGuid (Guid guid)
{
WriteBytes (guid.ToByteArray ());
}
}
class StringHeapBuffer : HeapBuffer {
protected Dictionary<string, uint> strings = new Dictionary<string, uint> (StringComparer.Ordinal);
public sealed override bool IsEmpty {
get { return length <= 1; }
}
public StringHeapBuffer ()
: base (1)
{
WriteByte (0);
}
public virtual uint GetStringIndex (string @string)
{
uint index;
if (strings.TryGetValue (@string, out index))
return index;
index = (uint) strings.Count + 1;
strings.Add (@string, index);
return index;
}
public uint [] WriteStrings ()
{
var sorted = SortStrings (strings);
strings = null;
// Add 1 for empty string whose index and offset are both 0
var string_offsets = new uint [sorted.Count + 1];
string_offsets [0] = 0;
// Find strings that can be folded
var previous = string.Empty;
foreach (var entry in sorted) {
var @string = entry.Key;
var index = entry.Value;
var position = base.position;
if (previous.EndsWith (@string, StringComparison.Ordinal) && !IsLowSurrogateChar (entry.Key [0])) {
// Map over the tail of prev string. Watch for null-terminator of prev string.
string_offsets [index] = (uint) (position - (Encoding.UTF8.GetByteCount (entry.Key) + 1));
} else {
string_offsets [index] = (uint) position;
WriteString (@string);
}
previous = entry.Key;
}
return string_offsets;
}
static List<KeyValuePair<string, uint>> SortStrings (Dictionary<string, uint> strings)
{
var sorted = new List<KeyValuePair<string, uint>> (strings);
sorted.Sort (new SuffixSort ());
return sorted;
}
static bool IsLowSurrogateChar (int c)
{
return unchecked((uint)(c - 0xDC00)) <= 0xDFFF - 0xDC00;
}
protected virtual void WriteString (string @string)
{
WriteBytes (Encoding.UTF8.GetBytes (@string));
WriteByte (0);
}
// Sorts strings such that a string is followed immediately by all strings
// that are a suffix of it.
private class SuffixSort : IComparer<KeyValuePair<string, uint>> {
public int Compare(KeyValuePair<string, uint> xPair, KeyValuePair<string, uint> yPair)
{
var x = xPair.Key;
var y = yPair.Key;
for (int i = x.Length - 1, j = y.Length - 1; i >= 0 & j >= 0; i--, j--) {
if (x [i] < y [j]) {
return -1;
}
if (x [i] > y [j]) {
return +1;
}
}
return y.Length.CompareTo (x.Length);
}
}
}
sealed class BlobHeapBuffer : HeapBuffer {
readonly Dictionary<ByteBuffer, uint> blobs = new Dictionary<ByteBuffer, uint> (new ByteBufferEqualityComparer ());
public override bool IsEmpty {
get { return length <= 1; }
}
public BlobHeapBuffer ()
: base (1)
{
WriteByte (0);
}
public uint GetBlobIndex (ByteBuffer blob)
{
uint index;
if (blobs.TryGetValue (blob, out index))
return index;
index = (uint) base.position;
WriteBlob (blob);
blobs.Add (blob, index);
return index;
}
void WriteBlob (ByteBuffer blob)
{
WriteCompressedUInt32 ((uint) blob.length);
WriteBytes (blob);
}
}
sealed class UserStringHeapBuffer : StringHeapBuffer {
public override uint GetStringIndex (string @string)
{
uint index;
if (strings.TryGetValue (@string, out index))
return index;
index = (uint) base.position;
WriteString (@string);
strings.Add (@string, index);
return index;
}
protected override void WriteString (string @string)
{
WriteCompressedUInt32 ((uint) @string.Length * 2 + 1);
byte special = 0;
for (int i = 0; i < @string.Length; i++) {
var @char = @string [i];
WriteUInt16 (@char);
if (special == 1)
continue;
if (@char < 0x20 || @char > 0x7e) {
if (@char > 0x7e
|| (@char >= 0x01 && @char <= 0x08)
|| (@char >= 0x0e && @char <= 0x1f)
|| @char == 0x27
|| @char == 0x2d) {
special = 1;
}
}
}
WriteByte (special);
}
}
sealed class PdbHeapBuffer : HeapBuffer {
public override bool IsEmpty {
get { return false; }
}
public PdbHeapBuffer ()
: base (0)
{
}
}
}
#endif
}
#endregion
#region Mono.Cecil.Metadata\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil.Metadata {
enum CodedIndex {
TypeDefOrRef,
HasConstant,
HasCustomAttribute,
HasFieldMarshal,
HasDeclSecurity,
MemberRefParent,
HasSemantics,
MethodDefOrRef,
MemberForwarded,
Implementation,
CustomAttributeType,
ResolutionScope,
TypeOrMethodDef,
HasCustomDebugInformation,
}
}
}
#endregion
#region Mono.Cecil.Metadata\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil.Metadata {
enum ElementType : byte {
None = 0x00,
Void = 0x01,
Boolean = 0x02,
Char = 0x03,
I1 = 0x04,
U1 = 0x05,
I2 = 0x06,
U2 = 0x07,
I4 = 0x08,
U4 = 0x09,
I8 = 0x0a,
U8 = 0x0b,
R4 = 0x0c,
R8 = 0x0d,
String = 0x0e,
Ptr = 0x0f, // Followed by <type> token
ByRef = 0x10, // Followed by <type> token
ValueType = 0x11, // Followed by <type> token
Class = 0x12, // Followed by <type> token
Var = 0x13, // Followed by generic parameter number
Array = 0x14, // <type> <rank> <boundsCount> <bound1> <loCount> <lo1>
GenericInst = 0x15, // <type> <type-arg-count> <type-1> ... <type-n> */
TypedByRef = 0x16,
I = 0x18, // System.IntPtr
U = 0x19, // System.UIntPtr
FnPtr = 0x1b, // Followed by full method signature
Object = 0x1c, // System.Object
SzArray = 0x1d, // Single-dim array with 0 lower bound
MVar = 0x1e, // Followed by generic parameter number
CModReqD = 0x1f, // Required modifier : followed by a TypeDef or TypeRef token
CModOpt = 0x20, // Optional modifier : followed by a TypeDef or TypeRef token
Internal = 0x21, // Implemented within the CLI
Modifier = 0x40, // Or'd with following element types
Sentinel = 0x41, // Sentinel for varargs method signature
Pinned = 0x45, // Denotes a local variable that points at a pinned object
// special undocumented constants
Type = 0x50,
Boxed = 0x51,
Enum = 0x55
}
}
}
#endregion
#region Mono.Cecil.Metadata\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil.Metadata {
sealed class GuidHeap : Heap {
public GuidHeap (byte [] data)
: base (data)
{
}
public Guid Read (uint index)
{
const int guid_size = 16;
if (index == 0 || ((index - 1) + guid_size) > data.Length)
return new Guid ();
var buffer = new byte [guid_size];
Buffer.BlockCopy (this.data, (int) ((index - 1) * guid_size), buffer, 0, guid_size);
return new Guid (buffer);
}
}
}
}
#endregion
#region Mono.Cecil.Metadata\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil.Metadata {
abstract class Heap {
public int IndexSize;
readonly internal byte [] data;
protected Heap (byte [] data)
{
this.data = data;
}
}
}
}
#endregion
#region Mono.Cecil.Metadata\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil {
internal struct MetadataToken : IEquatable<MetadataToken> {
readonly uint token;
public uint RID {
get { return token & 0x00ffffff; }
}
public TokenType TokenType {
get { return (TokenType) (token & 0xff000000); }
}
public static readonly MetadataToken Zero = new MetadataToken ((uint) 0);
public MetadataToken (uint token)
{
this.token = token;
}
public MetadataToken (TokenType type)
: this (type, 0)
{
}
public MetadataToken (TokenType type, uint rid)
{
token = (uint) type | rid;
}
public MetadataToken (TokenType type, int rid)
{
token = (uint) type | (uint) rid;
}
public int ToInt32 ()
{
return (int) token;
}
public uint ToUInt32 ()
{
return token;
}
public override int GetHashCode ()
{
return (int) token;
}
public bool Equals (MetadataToken other)
{
return other.token == token;
}
public override bool Equals (object obj)
{
if (obj is MetadataToken) {
var other = (MetadataToken) obj;
return other.token == token;
}
return false;
}
public static bool operator == (MetadataToken one, MetadataToken other)
{
return one.token == other.token;
}
public static bool operator != (MetadataToken one, MetadataToken other)
{
return one.token != other.token;
}
public override string ToString ()
{
return string.Format ("[{0}:0x{1}]", TokenType, RID.ToString ("x4"));
}
}
}
}
#endregion
#region Mono.Cecil.Metadata\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using Mono.Cecil.PE;
using RID = System.UInt32;
namespace Mono.Cecil.Metadata {
sealed class PdbHeap : Heap {
public byte [] Id;
public RID EntryPoint;
public long TypeSystemTables;
public uint [] TypeSystemTableRows;
public PdbHeap (byte [] data)
: base (data)
{
}
public bool HasTable (Table table)
{
return (TypeSystemTables & (1L << (int) table)) != 0;
}
}
}
}
#endregion
#region Mono.Cecil.Metadata\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System.Collections.Generic;
namespace Mono.Cecil.Metadata {
struct Row<T1, T2> {
internal T1 Col1;
internal T2 Col2;
public Row (T1 col1, T2 col2)
{
Col1 = col1;
Col2 = col2;
}
}
struct Row<T1, T2, T3> {
internal T1 Col1;
internal T2 Col2;
internal T3 Col3;
public Row (T1 col1, T2 col2, T3 col3)
{
Col1 = col1;
Col2 = col2;
Col3 = col3;
}
}
struct Row<T1, T2, T3, T4> {
internal T1 Col1;
internal T2 Col2;
internal T3 Col3;
internal T4 Col4;
public Row (T1 col1, T2 col2, T3 col3, T4 col4)
{
Col1 = col1;
Col2 = col2;
Col3 = col3;
Col4 = col4;
}
}
struct Row<T1, T2, T3, T4, T5> {
internal T1 Col1;
internal T2 Col2;
internal T3 Col3;
internal T4 Col4;
internal T5 Col5;
public Row (T1 col1, T2 col2, T3 col3, T4 col4, T5 col5)
{
Col1 = col1;
Col2 = col2;
Col3 = col3;
Col4 = col4;
Col5 = col5;
}
}
struct Row<T1, T2, T3, T4, T5, T6> {
internal T1 Col1;
internal T2 Col2;
internal T3 Col3;
internal T4 Col4;
internal T5 Col5;
internal T6 Col6;
public Row (T1 col1, T2 col2, T3 col3, T4 col4, T5 col5, T6 col6)
{
Col1 = col1;
Col2 = col2;
Col3 = col3;
Col4 = col4;
Col5 = col5;
Col6 = col6;
}
}
struct Row<T1, T2, T3, T4, T5, T6, T7, T8, T9> {
internal T1 Col1;
internal T2 Col2;
internal T3 Col3;
internal T4 Col4;
internal T5 Col5;
internal T6 Col6;
internal T7 Col7;
internal T8 Col8;
internal T9 Col9;
public Row (T1 col1, T2 col2, T3 col3, T4 col4, T5 col5, T6 col6, T7 col7, T8 col8, T9 col9)
{
Col1 = col1;
Col2 = col2;
Col3 = col3;
Col4 = col4;
Col5 = col5;
Col6 = col6;
Col7 = col7;
Col8 = col8;
Col9 = col9;
}
}
sealed class RowEqualityComparer : IEqualityComparer<Row<string, string>>, IEqualityComparer<Row<uint, uint>>, IEqualityComparer<Row<uint, uint, uint>> {
public bool Equals (Row<string, string> x, Row<string, string> y)
{
return x.Col1 == y.Col1
&& x.Col2 == y.Col2;
}
public int GetHashCode (Row<string, string> obj)
{
string x = obj.Col1, y = obj.Col2;
return (x != null ? x.GetHashCode () : 0) ^ (y != null ? y.GetHashCode () : 0);
}
public bool Equals (Row<uint, uint> x, Row<uint, uint> y)
{
return x.Col1 == y.Col1
&& x.Col2 == y.Col2;
}
public int GetHashCode (Row<uint, uint> obj)
{
return (int) (obj.Col1 ^ obj.Col2);
}
public bool Equals (Row<uint, uint, uint> x, Row<uint, uint, uint> y)
{
return x.Col1 == y.Col1
&& x.Col2 == y.Col2
&& x.Col3 == y.Col3;
}
public int GetHashCode (Row<uint, uint, uint> obj)
{
return (int) (obj.Col1 ^ obj.Col2 ^ obj.Col3);
}
}
}
}
#endregion
#region Mono.Cecil.Metadata\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Collections.Generic;
using System.Text;
namespace Mono.Cecil.Metadata {
class StringHeap : Heap {
readonly Dictionary<uint, string> strings = new Dictionary<uint, string> ();
public StringHeap (byte [] data)
: base (data)
{
}
public string Read (uint index)
{
if (index == 0)
return string.Empty;
string @string;
if (strings.TryGetValue (index, out @string))
return @string;
if (index > data.Length - 1)
return string.Empty;
@string = ReadStringAt (index);
if (@string.Length != 0)
strings.Add (index, @string);
return @string;
}
protected virtual string ReadStringAt (uint index)
{
int length = 0;
int start = (int) index;
for (int i = start; ; i++) {
if (data [i] == 0)
break;
length++;
}
return Encoding.UTF8.GetString (data, start, length);
}
}
}
}
#endregion
#region Mono.Cecil.Metadata\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Cecil.PE;
namespace Mono.Cecil.Metadata {
enum Table : byte {
Module = 0x00,
TypeRef = 0x01,
TypeDef = 0x02,
FieldPtr = 0x03,
Field = 0x04,
MethodPtr = 0x05,
Method = 0x06,
ParamPtr = 0x07,
Param = 0x08,
InterfaceImpl = 0x09,
MemberRef = 0x0a,
Constant = 0x0b,
CustomAttribute = 0x0c,
FieldMarshal = 0x0d,
DeclSecurity = 0x0e,
ClassLayout = 0x0f,
FieldLayout = 0x10,
StandAloneSig = 0x11,
EventMap = 0x12,
EventPtr = 0x13,
Event = 0x14,
PropertyMap = 0x15,
PropertyPtr = 0x16,
Property = 0x17,
MethodSemantics = 0x18,
MethodImpl = 0x19,
ModuleRef = 0x1a,
TypeSpec = 0x1b,
ImplMap = 0x1c,
FieldRVA = 0x1d,
EncLog = 0x1e,
EncMap = 0x1f,
Assembly = 0x20,
AssemblyProcessor = 0x21,
AssemblyOS = 0x22,
AssemblyRef = 0x23,
AssemblyRefProcessor = 0x24,
AssemblyRefOS = 0x25,
File = 0x26,
ExportedType = 0x27,
ManifestResource = 0x28,
NestedClass = 0x29,
GenericParam = 0x2a,
MethodSpec = 0x2b,
GenericParamConstraint = 0x2c,
Document = 0x30,
MethodDebugInformation = 0x31,
LocalScope = 0x32,
LocalVariable = 0x33,
LocalConstant = 0x34,
ImportScope = 0x35,
StateMachineMethod = 0x36,
CustomDebugInformation = 0x37,
}
struct TableInformation {
public uint Offset;
public uint Length;
public uint RowSize;
public bool IsLarge {
get { return Length > ushort.MaxValue; }
}
}
sealed class TableHeap : Heap {
public long Valid;
public long Sorted;
public readonly TableInformation [] Tables = new TableInformation [Mixin.TableCount];
public TableInformation this [Table table] {
get { return Tables [(int) table]; }
}
public TableHeap (byte [] data)
: base (data)
{
}
public bool HasTable (Table table)
{
return (Valid & (1L << (int) table)) != 0;
}
}
}
}
#endregion
#region Mono.Cecil.Metadata\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil {
internal enum TokenType : uint {
Module = 0x00000000,
TypeRef = 0x01000000,
TypeDef = 0x02000000,
Field = 0x04000000,
Method = 0x06000000,
Param = 0x08000000,
InterfaceImpl = 0x09000000,
MemberRef = 0x0a000000,
CustomAttribute = 0x0c000000,
Permission = 0x0e000000,
Signature = 0x11000000,
Event = 0x14000000,
Property = 0x17000000,
ModuleRef = 0x1a000000,
TypeSpec = 0x1b000000,
Assembly = 0x20000000,
AssemblyRef = 0x23000000,
File = 0x26000000,
ExportedType = 0x27000000,
ManifestResource = 0x28000000,
GenericParam = 0x2a000000,
MethodSpec = 0x2b000000,
GenericParamConstraint = 0x2c000000,
Document = 0x30000000,
MethodDebugInformation = 0x31000000,
LocalScope = 0x32000000,
LocalVariable = 0x33000000,
LocalConstant = 0x34000000,
ImportScope = 0x35000000,
StateMachineMethod = 0x36000000,
CustomDebugInformation = 0x37000000,
String = 0x70000000,
}
}
}
#endregion
#region Mono.Cecil.Metadata\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
namespace Mono.Cecil.Metadata {
sealed class UserStringHeap : StringHeap {
public UserStringHeap (byte [] data)
: base (data)
{
}
protected override string ReadStringAt (uint index)
{
int start = (int) index;
uint length = (uint) (data.ReadCompressedUInt32 (ref start) & ~1);
if (length < 1)
return string.Empty;
var chars = new char [length / 2];
for (int i = start, j = 0; i < start + length; i += 2)
chars [j++] = (char) (data [i] | (data [i + 1] << 8));
return new string (chars);
}
}
}
}
#endregion
#region Mono.Cecil.Metadata\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using Mono.Cecil.Metadata;
namespace Mono.Cecil {
static partial class Mixin {
public const int TableCount = 58;
public const int CodedIndexCount = 14;
public static uint ReadCompressedUInt32 (this byte [] data, ref int position)
{
uint integer;
if ((data [position] & 0x80) == 0) {
integer = data [position];
position++;
} else if ((data [position] & 0x40) == 0) {
integer = (uint) (data [position] & ~0x80) << 8;
integer |= data [position + 1];
position += 2;
} else {
integer = (uint) (data [position] & ~0xc0) << 24;
integer |= (uint) data [position + 1] << 16;
integer |= (uint) data [position + 2] << 8;
integer |= (uint) data [position + 3];
position += 4;
}
return integer;
}
public static MetadataToken GetMetadataToken (this CodedIndex self, uint data)
{
uint rid;
TokenType token_type;
switch (self) {
case CodedIndex.TypeDefOrRef:
rid = data >> 2;
switch (data & 3) {
case 0:
token_type = TokenType.TypeDef; goto ret;
case 1:
token_type = TokenType.TypeRef; goto ret;
case 2:
token_type = TokenType.TypeSpec; goto ret;
default:
goto exit;
}
case CodedIndex.HasConstant:
rid = data >> 2;
switch (data & 3) {
case 0:
token_type = TokenType.Field; goto ret;
case 1:
token_type = TokenType.Param; goto ret;
case 2:
token_type = TokenType.Property; goto ret;
default:
goto exit;
}
case CodedIndex.HasCustomAttribute:
rid = data >> 5;
switch (data & 31) {
case 0:
token_type = TokenType.Method; goto ret;
case 1:
token_type = TokenType.Field; goto ret;
case 2:
token_type = TokenType.TypeRef; goto ret;
case 3:
token_type = TokenType.TypeDef; goto ret;
case 4:
token_type = TokenType.Param; goto ret;
case 5:
token_type = TokenType.InterfaceImpl; goto ret;
case 6:
token_type = TokenType.MemberRef; goto ret;
case 7:
token_type = TokenType.Module; goto ret;
case 8:
token_type = TokenType.Permission; goto ret;
case 9:
token_type = TokenType.Property; goto ret;
case 10:
token_type = TokenType.Event; goto ret;
case 11:
token_type = TokenType.Signature; goto ret;
case 12:
token_type = TokenType.ModuleRef; goto ret;
case 13:
token_type = TokenType.TypeSpec; goto ret;
case 14:
token_type = TokenType.Assembly; goto ret;
case 15:
token_type = TokenType.AssemblyRef; goto ret;
case 16:
token_type = TokenType.File; goto ret;
case 17:
token_type = TokenType.ExportedType; goto ret;
case 18:
token_type = TokenType.ManifestResource; goto ret;
case 19:
token_type = TokenType.GenericParam; goto ret;
case 20:
token_type = TokenType.GenericParamConstraint; goto ret;
case 21:
token_type = TokenType.MethodSpec; goto ret;
default:
goto exit;
}
case CodedIndex.HasFieldMarshal:
rid = data >> 1;
switch (data & 1) {
case 0:
token_type = TokenType.Field; goto ret;
case 1:
token_type = TokenType.Param; goto ret;
default:
goto exit;
}
case CodedIndex.HasDeclSecurity:
rid = data >> 2;
switch (data & 3) {
case 0:
token_type = TokenType.TypeDef; goto ret;
case 1:
token_type = TokenType.Method; goto ret;
case 2:
token_type = TokenType.Assembly; goto ret;
default:
goto exit;
}
case CodedIndex.MemberRefParent:
rid = data >> 3;
switch (data & 7) {
case 0:
token_type = TokenType.TypeDef; goto ret;
case 1:
token_type = TokenType.TypeRef; goto ret;
case 2:
token_type = TokenType.ModuleRef; goto ret;
case 3:
token_type = TokenType.Method; goto ret;
case 4:
token_type = TokenType.TypeSpec; goto ret;
default:
goto exit;
}
case CodedIndex.HasSemantics:
rid = data >> 1;
switch (data & 1) {
case 0:
token_type = TokenType.Event; goto ret;
case 1:
token_type = TokenType.Property; goto ret;
default:
goto exit;
}
case CodedIndex.MethodDefOrRef:
rid = data >> 1;
switch (data & 1) {
case 0:
token_type = TokenType.Method; goto ret;
case 1:
token_type = TokenType.MemberRef; goto ret;
default:
goto exit;
}
case CodedIndex.MemberForwarded:
rid = data >> 1;
switch (data & 1) {
case 0:
token_type = TokenType.Field; goto ret;
case 1:
token_type = TokenType.Method; goto ret;
default:
goto exit;
}
case CodedIndex.Implementation:
rid = data >> 2;
switch (data & 3) {
case 0:
token_type = TokenType.File; goto ret;
case 1:
token_type = TokenType.AssemblyRef; goto ret;
case 2:
token_type = TokenType.ExportedType; goto ret;
default:
goto exit;
}
case CodedIndex.CustomAttributeType:
rid = data >> 3;
switch (data & 7) {
case 2:
token_type = TokenType.Method; goto ret;
case 3:
token_type = TokenType.MemberRef; goto ret;
default:
goto exit;
}
case CodedIndex.ResolutionScope:
rid = data >> 2;
switch (data & 3) {
case 0:
token_type = TokenType.Module; goto ret;
case 1:
token_type = TokenType.ModuleRef; goto ret;
case 2:
token_type = TokenType.AssemblyRef; goto ret;
case 3:
token_type = TokenType.TypeRef; goto ret;
default:
goto exit;
}
case CodedIndex.TypeOrMethodDef:
rid = data >> 1;
switch (data & 1) {
case 0:
token_type = TokenType.TypeDef; goto ret;
case 1:
token_type = TokenType.Method; goto ret;
default: goto exit;
}
case CodedIndex.HasCustomDebugInformation:
rid = data >> 5;
switch (data & 31) {
case 0:
token_type = TokenType.Method; goto ret;
case 1:
token_type = TokenType.Field; goto ret;
case 2:
token_type = TokenType.TypeRef; goto ret;
case 3:
token_type = TokenType.TypeDef; goto ret;
case 4:
token_type = TokenType.Param; goto ret;
case 5:
token_type = TokenType.InterfaceImpl; goto ret;
case 6:
token_type = TokenType.MemberRef; goto ret;
case 7:
token_type = TokenType.Module; goto ret;
case 8:
token_type = TokenType.Permission; goto ret;
case 9:
token_type = TokenType.Property; goto ret;
case 10:
token_type = TokenType.Event; goto ret;
case 11:
token_type = TokenType.Signature; goto ret;
case 12:
token_type = TokenType.ModuleRef; goto ret;
case 13:
token_type = TokenType.TypeSpec; goto ret;
case 14:
token_type = TokenType.Assembly; goto ret;
case 15:
token_type = TokenType.AssemblyRef; goto ret;
case 16:
token_type = TokenType.File; goto ret;
case 17:
token_type = TokenType.ExportedType; goto ret;
case 18:
token_type = TokenType.ManifestResource; goto ret;
case 19:
token_type = TokenType.GenericParam; goto ret;
case 20:
token_type = TokenType.GenericParamConstraint; goto ret;
case 21:
token_type = TokenType.MethodSpec; goto ret;
case 22:
token_type = TokenType.Document; goto ret;
case 23:
token_type = TokenType.LocalScope; goto ret;
case 24:
token_type = TokenType.LocalVariable; goto ret;
case 25:
token_type = TokenType.LocalConstant; goto ret;
case 26:
token_type = TokenType.ImportScope; goto ret;
default:
goto exit;
}
default:
goto exit;
}
ret:
return new MetadataToken (token_type, rid);
exit:
return MetadataToken.Zero;
}
#if !READ_ONLY
public static uint CompressMetadataToken (this CodedIndex self, MetadataToken token)
{
uint ret = 0;
if (token.RID == 0)
return ret;
switch (self) {
case CodedIndex.TypeDefOrRef:
ret = token.RID << 2;
switch (token.TokenType) {
case TokenType.TypeDef:
return ret | 0;
case TokenType.TypeRef:
return ret | 1;
case TokenType.TypeSpec:
return ret | 2;
default:
goto exit;
}
case CodedIndex.HasConstant:
ret = token.RID << 2;
switch (token.TokenType) {
case TokenType.Field:
return ret | 0;
case TokenType.Param:
return ret | 1;
case TokenType.Property:
return ret | 2;
default:
goto exit;
}
case CodedIndex.HasCustomAttribute:
ret = token.RID << 5;
switch (token.TokenType) {
case TokenType.Method:
return ret | 0;
case TokenType.Field:
return ret | 1;
case TokenType.TypeRef:
return ret | 2;
case TokenType.TypeDef:
return ret | 3;
case TokenType.Param:
return ret | 4;
case TokenType.InterfaceImpl:
return ret | 5;
case TokenType.MemberRef:
return ret | 6;
case TokenType.Module:
return ret | 7;
case TokenType.Permission:
return ret | 8;
case TokenType.Property:
return ret | 9;
case TokenType.Event:
return ret | 10;
case TokenType.Signature:
return ret | 11;
case TokenType.ModuleRef:
return ret | 12;
case TokenType.TypeSpec:
return ret | 13;
case TokenType.Assembly:
return ret | 14;
case TokenType.AssemblyRef:
return ret | 15;
case TokenType.File:
return ret | 16;
case TokenType.ExportedType:
return ret | 17;
case TokenType.ManifestResource:
return ret | 18;
case TokenType.GenericParam:
return ret | 19;
case TokenType.GenericParamConstraint:
return ret | 20;
case TokenType.MethodSpec:
return ret | 21;
default:
goto exit;
}
case CodedIndex.HasFieldMarshal:
ret = token.RID << 1;
switch (token.TokenType) {
case TokenType.Field:
return ret | 0;
case TokenType.Param:
return ret | 1;
default:
goto exit;
}
case CodedIndex.HasDeclSecurity:
ret = token.RID << 2;
switch (token.TokenType) {
case TokenType.TypeDef:
return ret | 0;
case TokenType.Method:
return ret | 1;
case TokenType.Assembly:
return ret | 2;
default:
goto exit;
}
case CodedIndex.MemberRefParent:
ret = token.RID << 3;
switch (token.TokenType) {
case TokenType.TypeDef:
return ret | 0;
case TokenType.TypeRef:
return ret | 1;
case TokenType.ModuleRef:
return ret | 2;
case TokenType.Method:
return ret | 3;
case TokenType.TypeSpec:
return ret | 4;
default:
goto exit;
}
case CodedIndex.HasSemantics:
ret = token.RID << 1;
switch (token.TokenType) {
case TokenType.Event:
return ret | 0;
case TokenType.Property:
return ret | 1;
default:
goto exit;
}
case CodedIndex.MethodDefOrRef:
ret = token.RID << 1;
switch (token.TokenType) {
case TokenType.Method:
return ret | 0;
case TokenType.MemberRef:
return ret | 1;
default:
goto exit;
}
case CodedIndex.MemberForwarded:
ret = token.RID << 1;
switch (token.TokenType) {
case TokenType.Field:
return ret | 0;
case TokenType.Method:
return ret | 1;
default:
goto exit;
}
case CodedIndex.Implementation:
ret = token.RID << 2;
switch (token.TokenType) {
case TokenType.File:
return ret | 0;
case TokenType.AssemblyRef:
return ret | 1;
case TokenType.ExportedType:
return ret | 2;
default:
goto exit;
}
case CodedIndex.CustomAttributeType:
ret = token.RID << 3;
switch (token.TokenType) {
case TokenType.Method:
return ret | 2;
case TokenType.MemberRef:
return ret | 3;
default:
goto exit;
}
case CodedIndex.ResolutionScope:
ret = token.RID << 2;
switch (token.TokenType) {
case TokenType.Module:
return ret | 0;
case TokenType.ModuleRef:
return ret | 1;
case TokenType.AssemblyRef:
return ret | 2;
case TokenType.TypeRef:
return ret | 3;
default:
goto exit;
}
case CodedIndex.TypeOrMethodDef:
ret = token.RID << 1;
switch (token.TokenType) {
case TokenType.TypeDef:
return ret | 0;
case TokenType.Method:
return ret | 1;
default:
goto exit;
}
case CodedIndex.HasCustomDebugInformation:
ret = token.RID << 5;
switch (token.TokenType) {
case TokenType.Method:
return ret | 0;
case TokenType.Field:
return ret | 1;
case TokenType.TypeRef:
return ret | 2;
case TokenType.TypeDef:
return ret | 3;
case TokenType.Param:
return ret | 4;
case TokenType.InterfaceImpl:
return ret | 5;
case TokenType.MemberRef:
return ret | 6;
case TokenType.Module:
return ret | 7;
case TokenType.Permission:
return ret | 8;
case TokenType.Property:
return ret | 9;
case TokenType.Event:
return ret | 10;
case TokenType.Signature:
return ret | 11;
case TokenType.ModuleRef:
return ret | 12;
case TokenType.TypeSpec:
return ret | 13;
case TokenType.Assembly:
return ret | 14;
case TokenType.AssemblyRef:
return ret | 15;
case TokenType.File:
return ret | 16;
case TokenType.ExportedType:
return ret | 17;
case TokenType.ManifestResource:
return ret | 18;
case TokenType.GenericParam:
return ret | 19;
case TokenType.GenericParamConstraint:
return ret | 20;
case TokenType.MethodSpec:
return ret | 21;
case TokenType.Document:
return ret | 22;
case TokenType.LocalScope:
return ret | 23;
case TokenType.LocalVariable:
return ret | 24;
case TokenType.LocalConstant:
return ret | 25;
case TokenType.ImportScope:
return ret | 26;
default:
goto exit;
}
default:
goto exit;
}
exit:
throw new ArgumentException ();
}
#endif
public static int GetSize (this CodedIndex self, Func<Table, int> counter)
{
int bits;
Table [] tables;
switch (self) {
case CodedIndex.TypeDefOrRef:
bits = 2;
tables = new [] { Table.TypeDef, Table.TypeRef, Table.TypeSpec };
break;
case CodedIndex.HasConstant:
bits = 2;
tables = new [] { Table.Field, Table.Param, Table.Property };
break;
case CodedIndex.HasCustomAttribute:
bits = 5;
tables = new [] {
Table.Method, Table.Field, Table.TypeRef, Table.TypeDef, Table.Param, Table.InterfaceImpl, Table.MemberRef,
Table.Module, Table.DeclSecurity, Table.Property, Table.Event, Table.StandAloneSig, Table.ModuleRef,
Table.TypeSpec, Table.Assembly, Table.AssemblyRef, Table.File, Table.ExportedType,
Table.ManifestResource, Table.GenericParam, Table.GenericParamConstraint, Table.MethodSpec,
};
break;
case CodedIndex.HasFieldMarshal:
bits = 1;
tables = new [] { Table.Field, Table.Param };
break;
case CodedIndex.HasDeclSecurity:
bits = 2;
tables = new [] { Table.TypeDef, Table.Method, Table.Assembly };
break;
case CodedIndex.MemberRefParent:
bits = 3;
tables = new [] { Table.TypeDef, Table.TypeRef, Table.ModuleRef, Table.Method, Table.TypeSpec };
break;
case CodedIndex.HasSemantics:
bits = 1;
tables = new [] { Table.Event, Table.Property };
break;
case CodedIndex.MethodDefOrRef:
bits = 1;
tables = new [] { Table.Method, Table.MemberRef };
break;
case CodedIndex.MemberForwarded:
bits = 1;
tables = new [] { Table.Field, Table.Method };
break;
case CodedIndex.Implementation:
bits = 2;
tables = new [] { Table.File, Table.AssemblyRef, Table.ExportedType };
break;
case CodedIndex.CustomAttributeType:
bits = 3;
tables = new [] { Table.Method, Table.MemberRef };
break;
case CodedIndex.ResolutionScope:
bits = 2;
tables = new [] { Table.Module, Table.ModuleRef, Table.AssemblyRef, Table.TypeRef };
break;
case CodedIndex.TypeOrMethodDef:
bits = 1;
tables = new [] { Table.TypeDef, Table.Method };
break;
case CodedIndex.HasCustomDebugInformation:
bits = 5;
tables = new[] {
Table.Method, Table.Field, Table.TypeRef, Table.TypeDef, Table.Param, Table.InterfaceImpl, Table.MemberRef,
Table.Module, Table.DeclSecurity, Table.Property, Table.Event, Table.StandAloneSig, Table.ModuleRef,
Table.TypeSpec, Table.Assembly, Table.AssemblyRef, Table.File, Table.ExportedType,
Table.ManifestResource, Table.GenericParam, Table.GenericParamConstraint, Table.MethodSpec,
Table.Document, Table.LocalScope, Table.LocalVariable, Table.LocalConstant, Table.ImportScope,
};
break;
default:
throw new ArgumentException ();
}
int max = 0;
for (int i = 0; i < tables.Length; i++) {
max = System.Math.Max (counter (tables [i]), max);
}
return max < (1 << (16 - bits)) ? 2 : 4;
}
}
}
}
#endregion
#region Mono.Cecil.PE\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.IO;
namespace Mono.Cecil.PE {
class BinaryStreamReader : BinaryReader {
public int Position {
get { return (int) BaseStream.Position; }
set { BaseStream.Position = value; }
}
public int Length {
get { return (int) BaseStream.Length; }
}
public BinaryStreamReader (Stream stream)
: base (stream)
{
}
public void Advance (int bytes)
{
BaseStream.Seek (bytes, SeekOrigin.Current);
}
public void MoveTo (uint position)
{
BaseStream.Seek (position, SeekOrigin.Begin);
}
public void Align (int align)
{
align--;
var position = Position;
Advance (((position + align) & ~align) - position);
}
public DataDirectory ReadDataDirectory ()
{
return new DataDirectory (ReadUInt32 (), ReadUInt32 ());
}
}
}
}
#endregion
#region Mono.Cecil.PE\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.IO;
#if !READ_ONLY
namespace Mono.Cecil.PE {
class BinaryStreamWriter : BinaryWriter {
public int Position {
get { return (int) BaseStream.Position; }
set { BaseStream.Position = value; }
}
public BinaryStreamWriter (Stream stream)
: base (stream)
{
}
public void WriteByte (byte value)
{
Write (value);
}
public void WriteUInt16 (ushort value)
{
Write (value);
}
public void WriteInt16 (short value)
{
Write (value);
}
public void WriteUInt32 (uint value)
{
Write (value);
}
public void WriteInt32 (int value)
{
Write (value);
}
public void WriteUInt64 (ulong value)
{
Write (value);
}
public void WriteBytes (byte [] bytes)
{
Write (bytes);
}
public void WriteDataDirectory (DataDirectory directory)
{
Write (directory.VirtualAddress);
Write (directory.Size);
}
public void WriteBuffer (ByteBuffer buffer)
{
Write (buffer.buffer, 0, buffer.length);
}
protected void Advance (int bytes)
{
BaseStream.Seek (bytes, SeekOrigin.Current);
}
public void Align (int align)
{
align--;
var position = Position;
var bytes = ((position + align) & ~align) - position;
for (int i = 0; i < bytes; i++)
WriteByte (0);
}
}
}
#endif
}
#endregion
#region Mono.Cecil.PE\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
namespace Mono.Cecil.PE {
class ByteBuffer {
internal byte [] buffer;
internal int length;
internal int position;
public ByteBuffer ()
{
this.buffer = Empty<byte>.Array;
}
public ByteBuffer (int length)
{
this.buffer = new byte [length];
}
public ByteBuffer (byte [] buffer)
{
this.buffer = buffer ?? Empty<byte>.Array;
this.length = this.buffer.Length;
}
public void Advance (int length)
{
position += length;
}
public byte ReadByte ()
{
return buffer [position++];
}
public sbyte ReadSByte ()
{
return (sbyte) ReadByte ();
}
public byte [] ReadBytes (int length)
{
var bytes = new byte [length];
Buffer.BlockCopy (buffer, position, bytes, 0, length);
position += length;
return bytes;
}
public ushort ReadUInt16 ()
{
ushort value = (ushort) (buffer [position]
| (buffer [position + 1] << 8));
position += 2;
return value;
}
public short ReadInt16 ()
{
return (short) ReadUInt16 ();
}
public uint ReadUInt32 ()
{
uint value = (uint) (buffer [position]
| (buffer [position + 1] << 8)
| (buffer [position + 2] << 16)
| (buffer [position + 3] << 24));
position += 4;
return value;
}
public int ReadInt32 ()
{
return (int) ReadUInt32 ();
}
public ulong ReadUInt64 ()
{
uint low = ReadUInt32 ();
uint high = ReadUInt32 ();
return (((ulong) high) << 32) | low;
}
public long ReadInt64 ()
{
return (long) ReadUInt64 ();
}
public uint ReadCompressedUInt32 ()
{
byte first = ReadByte ();
if ((first & 0x80) == 0)
return first;
if ((first & 0x40) == 0)
return ((uint) (first & ~0x80) << 8)
| ReadByte ();
return ((uint) (first & ~0xc0) << 24)
| (uint) ReadByte () << 16
| (uint) ReadByte () << 8
| ReadByte ();
}
public int ReadCompressedInt32 ()
{
var b = buffer [position];
var u = (int) ReadCompressedUInt32 ();
var v = u >> 1;
if ((u & 1) == 0)
return v;
switch (b & 0xc0)
{
case 0:
case 0x40:
return v - 0x40;
case 0x80:
return v - 0x2000;
default:
return v - 0x10000000;
}
}
public float ReadSingle ()
{
if (!BitConverter.IsLittleEndian) {
var bytes = ReadBytes (4);
Array.Reverse (bytes);
return BitConverter.ToSingle (bytes, 0);
}
float value = BitConverter.ToSingle (buffer, position);
position += 4;
return value;
}
public double ReadDouble ()
{
if (!BitConverter.IsLittleEndian) {
var bytes = ReadBytes (8);
Array.Reverse (bytes);
return BitConverter.ToDouble (bytes, 0);
}
double value = BitConverter.ToDouble (buffer, position);
position += 8;
return value;
}
#if !READ_ONLY
public void WriteByte (byte value)
{
if (position == buffer.Length)
Grow (1);
buffer [position++] = value;
if (position > length)
length = position;
}
public void WriteSByte (sbyte value)
{
WriteByte ((byte) value);
}
public void WriteUInt16 (ushort value)
{
if (position + 2 > buffer.Length)
Grow (2);
buffer [position++] = (byte) value;
buffer [position++] = (byte) (value >> 8);
if (position > length)
length = position;
}
public void WriteInt16 (short value)
{
WriteUInt16 ((ushort) value);
}
public void WriteUInt32 (uint value)
{
if (position + 4 > buffer.Length)
Grow (4);
buffer [position++] = (byte) value;
buffer [position++] = (byte) (value >> 8);
buffer [position++] = (byte) (value >> 16);
buffer [position++] = (byte) (value >> 24);
if (position > length)
length = position;
}
public void WriteInt32 (int value)
{
WriteUInt32 ((uint) value);
}
public void WriteUInt64 (ulong value)
{
if (position + 8 > buffer.Length)
Grow (8);
buffer [position++] = (byte) value;
buffer [position++] = (byte) (value >> 8);
buffer [position++] = (byte) (value >> 16);
buffer [position++] = (byte) (value >> 24);
buffer [position++] = (byte) (value >> 32);
buffer [position++] = (byte) (value >> 40);
buffer [position++] = (byte) (value >> 48);
buffer [position++] = (byte) (value >> 56);
if (position > length)
length = position;
}
public void WriteInt64 (long value)
{
WriteUInt64 ((ulong) value);
}
public void WriteCompressedUInt32 (uint value)
{
if (value < 0x80)
WriteByte ((byte) value);
else if (value < 0x4000) {
WriteByte ((byte) (0x80 | (value >> 8)));
WriteByte ((byte) (value & 0xff));
} else {
WriteByte ((byte) ((value >> 24) | 0xc0));
WriteByte ((byte) ((value >> 16) & 0xff));
WriteByte ((byte) ((value >> 8) & 0xff));
WriteByte ((byte) (value & 0xff));
}
}
public void WriteCompressedInt32 (int value)
{
if (value >= 0) {
WriteCompressedUInt32 ((uint) (value << 1));
return;
}
if (value > -0x40)
value = 0x40 + value;
else if (value >= -0x2000)
value = 0x2000 + value;
else if (value >= -0x20000000)
value = 0x20000000 + value;
WriteCompressedUInt32 ((uint) ((value << 1) | 1));
}
public void WriteBytes (byte [] bytes)
{
var length = bytes.Length;
if (position + length > buffer.Length)
Grow (length);
Buffer.BlockCopy (bytes, 0, buffer, position, length);
position += length;
if (position > this.length)
this.length = position;
}
public void WriteBytes (int length)
{
if (position + length > buffer.Length)
Grow (length);
position += length;
if (position > this.length)
this.length = position;
}
public void WriteBytes (ByteBuffer buffer)
{
if (position + buffer.length > this.buffer.Length)
Grow (buffer.length);
Buffer.BlockCopy (buffer.buffer, 0, this.buffer, position, buffer.length);
position += buffer.length;
if (position > this.length)
this.length = position;
}
public void WriteSingle (float value)
{
var bytes = BitConverter.GetBytes (value);
if (!BitConverter.IsLittleEndian)
Array.Reverse (bytes);
WriteBytes (bytes);
}
public void WriteDouble (double value)
{
var bytes = BitConverter.GetBytes (value);
if (!BitConverter.IsLittleEndian)
Array.Reverse (bytes);
WriteBytes (bytes);
}
void Grow (int desired)
{
var current = this.buffer;
var current_length = current.Length;
var buffer = new byte [System.Math.Max (current_length + desired, current_length * 2)];
Buffer.BlockCopy (current, 0, buffer, 0, current_length);
this.buffer = buffer;
}
#endif
}
}
}
#endregion
#region Mono.Cecil.PE\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Collections.Generic;
namespace Mono.Cecil.PE {
sealed class ByteBufferEqualityComparer : IEqualityComparer<ByteBuffer> {
public bool Equals (ByteBuffer x, ByteBuffer y)
{
if (x.length != y.length)
return false;
var x_buffer = x.buffer;
var y_buffer = y.buffer;
for (int i = 0; i < x.length; i++)
if (x_buffer [i] != y_buffer [i])
return false;
return true;
}
public int GetHashCode (ByteBuffer buffer)
{
// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
const int fnv_offset_bias = unchecked((int)2166136261);
const int fnv_prime = 16777619;
var hash_code = fnv_offset_bias;
var bytes = buffer.buffer;
for (int i = 0; i < buffer.length; i++)
hash_code = unchecked ((hash_code ^ bytes [i]) * fnv_prime);
return hash_code;
}
}
}
}
#endregion
#region Mono.Cecil.PE\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using RVA = System.UInt32;
namespace Mono.Cecil.PE {
struct DataDirectory {
public readonly RVA VirtualAddress;
public readonly uint Size;
public bool IsZero {
get { return VirtualAddress == 0 && Size == 0; }
}
public DataDirectory (RVA rva, uint size)
{
this.VirtualAddress = rva;
this.Size = size;
}
}
}
}
#endregion
#region Mono.Cecil.PE\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.IO;
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
using Mono.Collections.Generic;
using RVA = System.UInt32;
namespace Mono.Cecil.PE {
sealed class Image : IDisposable {
public Disposable<Stream> Stream;
public string FileName;
public ModuleKind Kind;
public string RuntimeVersion;
public TargetArchitecture Architecture;
public ModuleCharacteristics Characteristics;
public ushort LinkerVersion;
public ImageDebugHeader DebugHeader;
public Section [] Sections;
public Section MetadataSection;
public uint EntryPointToken;
public uint Timestamp;
public ModuleAttributes Attributes;
public DataDirectory Win32Resources;
public DataDirectory Debug;
public DataDirectory Resources;
public DataDirectory StrongName;
public StringHeap StringHeap;
public BlobHeap BlobHeap;
public UserStringHeap UserStringHeap;
public GuidHeap GuidHeap;
public TableHeap TableHeap;
public PdbHeap PdbHeap;
readonly int [] coded_index_sizes = new int [14];
readonly Func<Table, int> counter;
public Image ()
{
counter = GetTableLength;
}
public bool HasTable (Table table)
{
return GetTableLength (table) > 0;
}
public int GetTableLength (Table table)
{
return (int) TableHeap [table].Length;
}
public int GetTableIndexSize (Table table)
{
return GetTableLength (table) < 65536 ? 2 : 4;
}
public int GetCodedIndexSize (CodedIndex coded_index)
{
var index = (int) coded_index;
var size = coded_index_sizes [index];
if (size != 0)
return size;
return coded_index_sizes [index] = coded_index.GetSize (counter);
}
public uint ResolveVirtualAddress (RVA rva)
{
var section = GetSectionAtVirtualAddress (rva);
if (section == null)
throw new ArgumentOutOfRangeException ();
return ResolveVirtualAddressInSection (rva, section);
}
public uint ResolveVirtualAddressInSection (RVA rva, Section section)
{
return rva + section.PointerToRawData - section.VirtualAddress;
}
public Section GetSection (string name)
{
var sections = this.Sections;
for (int i = 0; i < sections.Length; i++) {
var section = sections [i];
if (section.Name == name)
return section;
}
return null;
}
public Section GetSectionAtVirtualAddress (RVA rva)
{
var sections = this.Sections;
for (int i = 0; i < sections.Length; i++) {
var section = sections [i];
if (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.SizeOfRawData)
return section;
}
return null;
}
BinaryStreamReader GetReaderAt (RVA rva)
{
var section = GetSectionAtVirtualAddress (rva);
if (section == null)
return null;
var reader = new BinaryStreamReader (Stream.value);
reader.MoveTo (ResolveVirtualAddressInSection (rva, section));
return reader;
}
public TRet GetReaderAt<TItem, TRet> (RVA rva, TItem item, Func<TItem, BinaryStreamReader, TRet> read) where TRet : class
{
var position = Stream.value.Position;
try {
var reader = GetReaderAt (rva);
if (reader == null)
return null;
return read (item, reader);
} finally {
Stream.value.Position = position;
}
}
public bool HasDebugTables ()
{
return HasTable (Table.Document)
|| HasTable (Table.MethodDebugInformation)
|| HasTable (Table.LocalScope)
|| HasTable (Table.LocalVariable)
|| HasTable (Table.LocalConstant)
|| HasTable (Table.StateMachineMethod)
|| HasTable (Table.CustomDebugInformation);
}
public void Dispose ()
{
Stream.Dispose ();
}
}
}
}
#endregion
#region Mono.Cecil.PE\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.IO;
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
using Mono.Collections.Generic;
using RVA = System.UInt32;
namespace Mono.Cecil.PE {
sealed class ImageReader : BinaryStreamReader {
readonly Image image;
DataDirectory cli;
DataDirectory metadata;
uint table_heap_offset;
public ImageReader (Disposable<Stream> stream, string file_name)
: base (stream.value)
{
image = new Image ();
image.Stream = stream;
image.FileName = file_name;
}
void MoveTo (DataDirectory directory)
{
BaseStream.Position = image.ResolveVirtualAddress (directory.VirtualAddress);
}
void ReadImage ()
{
if (BaseStream.Length < 128)
throw new BadImageFormatException ();
// - DOSHeader
// PE 2
// Start 58
// Lfanew 4
// End 64
if (ReadUInt16 () != 0x5a4d)
throw new BadImageFormatException ();
Advance (58);
MoveTo (ReadUInt32 ());
if (ReadUInt32 () != 0x00004550)
throw new BadImageFormatException ();
// - PEFileHeader
// Machine 2
image.Architecture = ReadArchitecture ();
// NumberOfSections 2
ushort sections = ReadUInt16 ();
// TimeDateStamp 4
image.Timestamp = ReadUInt32 ();
// PointerToSymbolTable 4
// NumberOfSymbols 4
// OptionalHeaderSize 2
Advance (10);
// Characteristics 2
ushort characteristics = ReadUInt16 ();
ushort subsystem, dll_characteristics, linker_version;
ReadOptionalHeaders (out subsystem, out dll_characteristics, out linker_version);
ReadSections (sections);
ReadCLIHeader ();
ReadMetadata ();
ReadDebugHeader ();
image.Kind = GetModuleKind (characteristics, subsystem);
image.Characteristics = (ModuleCharacteristics) dll_characteristics;
image.LinkerVersion = linker_version;
}
TargetArchitecture ReadArchitecture ()
{
return (TargetArchitecture) ReadUInt16 ();
}
static ModuleKind GetModuleKind (ushort characteristics, ushort subsystem)
{
if ((characteristics & 0x2000) != 0) // ImageCharacteristics.Dll
return ModuleKind.Dll;
if (subsystem == 0x2 || subsystem == 0x9) // SubSystem.WindowsGui || SubSystem.WindowsCeGui
return ModuleKind.Windows;
return ModuleKind.Console;
}
void ReadOptionalHeaders (out ushort subsystem, out ushort dll_characteristics, out ushort linker)
{
// - PEOptionalHeader
// - StandardFieldsHeader
// Magic 2
bool pe64 = ReadUInt16 () == 0x20b;
// pe32 || pe64
linker = ReadUInt16 ();
// CodeSize 4
// InitializedDataSize 4
// UninitializedDataSize4
// EntryPointRVA 4
// BaseOfCode 4
// BaseOfData 4 || 0
// - NTSpecificFieldsHeader
// ImageBase 4 || 8
// SectionAlignment 4
// FileAlignement 4
// OSMajor 2
// OSMinor 2
// UserMajor 2
// UserMinor 2
// SubSysMajor 2
// SubSysMinor 2
// Reserved 4
// ImageSize 4
// HeaderSize 4
// FileChecksum 4
Advance (64);
// SubSystem 2
subsystem = ReadUInt16 ();
// DLLFlags 2
dll_characteristics = ReadUInt16 ();
// StackReserveSize 4 || 8
// StackCommitSize 4 || 8
// HeapReserveSize 4 || 8
// HeapCommitSize 4 || 8
// LoaderFlags 4
// NumberOfDataDir 4
// - DataDirectoriesHeader
// ExportTable 8
// ImportTable 8
Advance (pe64 ? 56 : 40);
// ResourceTable 8
image.Win32Resources = ReadDataDirectory ();
// ExceptionTable 8
// CertificateTable 8
// BaseRelocationTable 8
Advance (24);
// Debug 8
image.Debug = ReadDataDirectory ();
// Copyright 8
// GlobalPtr 8
// TLSTable 8
// LoadConfigTable 8
// BoundImport 8
// IAT 8
// DelayImportDescriptor8
Advance (56);
// CLIHeader 8
cli = ReadDataDirectory ();
if (cli.IsZero)
throw new BadImageFormatException ();
// Reserved 8
Advance (8);
}
string ReadAlignedString (int length)
{
int read = 0;
var buffer = new char [length];
while (read < length) {
var current = ReadByte ();
if (current == 0)
break;
buffer [read++] = (char) current;
}
Advance (-1 + ((read + 4) & ~3) - read);
return new string (buffer, 0, read);
}
string ReadZeroTerminatedString (int length)
{
int read = 0;
var buffer = new char [length];
var bytes = ReadBytes (length);
while (read < length) {
var current = bytes [read];
if (current == 0)
break;
buffer [read++] = (char) current;
}
return new string (buffer, 0, read);
}
void ReadSections (ushort count)
{
var sections = new Section [count];
for (int i = 0; i < count; i++) {
var section = new Section ();
// Name
section.Name = ReadZeroTerminatedString (8);
// VirtualSize 4
Advance (4);
// VirtualAddress 4
section.VirtualAddress = ReadUInt32 ();
// SizeOfRawData 4
section.SizeOfRawData = ReadUInt32 ();
// PointerToRawData 4
section.PointerToRawData = ReadUInt32 ();
// PointerToRelocations 4
// PointerToLineNumbers 4
// NumberOfRelocations 2
// NumberOfLineNumbers 2
// Characteristics 4
Advance (16);
sections [i] = section;
}
image.Sections = sections;
}
void ReadCLIHeader ()
{
MoveTo (cli);
// - CLIHeader
// Cb 4
// MajorRuntimeVersion 2
// MinorRuntimeVersion 2
Advance (8);
// Metadata 8
metadata = ReadDataDirectory ();
// Flags 4
image.Attributes = (ModuleAttributes) ReadUInt32 ();
// EntryPointToken 4
image.EntryPointToken = ReadUInt32 ();
// Resources 8
image.Resources = ReadDataDirectory ();
// StrongNameSignature 8
image.StrongName = ReadDataDirectory ();
// CodeManagerTable 8
// VTableFixups 8
// ExportAddressTableJumps 8
// ManagedNativeHeader 8
}
void ReadMetadata ()
{
MoveTo (metadata);
if (ReadUInt32 () != 0x424a5342)
throw new BadImageFormatException ();
// MajorVersion 2
// MinorVersion 2
// Reserved 4
Advance (8);
image.RuntimeVersion = ReadZeroTerminatedString (ReadInt32 ());
// Flags 2
Advance (2);
var streams = ReadUInt16 ();
var section = image.GetSectionAtVirtualAddress (metadata.VirtualAddress);
if (section == null)
throw new BadImageFormatException ();
image.MetadataSection = section;
for (int i = 0; i < streams; i++)
ReadMetadataStream (section);
if (image.PdbHeap != null)
ReadPdbHeap ();
if (image.TableHeap != null)
ReadTableHeap ();
}
void ReadDebugHeader ()
{
if (image.Debug.IsZero) {
image.DebugHeader = new ImageDebugHeader (Empty<ImageDebugHeaderEntry>.Array);
return;
}
MoveTo (image.Debug);
var entries = new ImageDebugHeaderEntry [(int) image.Debug.Size / ImageDebugDirectory.Size];
for (int i = 0; i < entries.Length; i++) {
var directory = new ImageDebugDirectory {
Characteristics = ReadInt32 (),
TimeDateStamp = ReadInt32 (),
MajorVersion = ReadInt16 (),
MinorVersion = ReadInt16 (),
Type = (ImageDebugType) ReadInt32 (),
SizeOfData = ReadInt32 (),
AddressOfRawData = ReadInt32 (),
PointerToRawData = ReadInt32 (),
};
if (directory.AddressOfRawData == 0) {
entries [i] = new ImageDebugHeaderEntry (directory, Empty<byte>.Array);
continue;
}
var position = Position;
try {
MoveTo ((uint) directory.PointerToRawData);
var data = ReadBytes (directory.SizeOfData);
entries [i] = new ImageDebugHeaderEntry (directory, data);
} finally {
Position = position;
}
}
image.DebugHeader = new ImageDebugHeader (entries);
}
void ReadMetadataStream (Section section)
{
// Offset 4
uint offset = metadata.VirtualAddress - section.VirtualAddress + ReadUInt32 (); // relative to the section start
// Size 4
uint size = ReadUInt32 ();
var data = ReadHeapData (offset, size);
var name = ReadAlignedString (16);
switch (name) {
case "#~":
case "#-":
image.TableHeap = new TableHeap (data);
table_heap_offset = offset;
break;
case "#Strings":
image.StringHeap = new StringHeap (data);
break;
case "#Blob":
image.BlobHeap = new BlobHeap (data);
break;
case "#GUID":
image.GuidHeap = new GuidHeap (data);
break;
case "#US":
image.UserStringHeap = new UserStringHeap (data);
break;
case "#Pdb":
image.PdbHeap = new PdbHeap (data);
break;
}
}
byte [] ReadHeapData (uint offset, uint size)
{
var position = BaseStream.Position;
MoveTo (offset + image.MetadataSection.PointerToRawData);
var data = ReadBytes ((int) size);
BaseStream.Position = position;
return data;
}
void ReadTableHeap ()
{
var heap = image.TableHeap;
MoveTo (table_heap_offset + image.MetadataSection.PointerToRawData);
// Reserved 4
// MajorVersion 1
// MinorVersion 1
Advance (6);
// HeapSizes 1
var sizes = ReadByte ();
// Reserved2 1
Advance (1);
// Valid 8
heap.Valid = ReadInt64 ();
// Sorted 8
heap.Sorted = ReadInt64 ();
if (image.PdbHeap != null) {
for (int i = 0; i < Mixin.TableCount; i++) {
if (!image.PdbHeap.HasTable ((Table) i))
continue;
heap.Tables [i].Length = image.PdbHeap.TypeSystemTableRows [i];
}
}
for (int i = 0; i < Mixin.TableCount; i++) {
if (!heap.HasTable ((Table) i))
continue;
heap.Tables [i].Length = ReadUInt32 ();
}
SetIndexSize (image.StringHeap, sizes, 0x1);
SetIndexSize (image.GuidHeap, sizes, 0x2);
SetIndexSize (image.BlobHeap, sizes, 0x4);
ComputeTableInformations ();
}
static void SetIndexSize (Heap heap, uint sizes, byte flag)
{
if (heap == null)
return;
heap.IndexSize = (sizes & flag) > 0 ? 4 : 2;
}
int GetTableIndexSize (Table table)
{
return image.GetTableIndexSize (table);
}
int GetCodedIndexSize (CodedIndex index)
{
return image.GetCodedIndexSize (index);
}
void ComputeTableInformations ()
{
uint offset = (uint) BaseStream.Position - table_heap_offset - image.MetadataSection.PointerToRawData; // header
int stridx_size = image.StringHeap.IndexSize;
int guididx_size = image.GuidHeap != null ? image.GuidHeap.IndexSize : 2;
int blobidx_size = image.BlobHeap != null ? image.BlobHeap.IndexSize : 2;
var heap = image.TableHeap;
var tables = heap.Tables;
for (int i = 0; i < Mixin.TableCount; i++) {
var table = (Table) i;
if (!heap.HasTable (table))
continue;
int size;
switch (table) {
case Table.Module:
size = 2 // Generation
+ stridx_size // Name
+ (guididx_size * 3); // Mvid, EncId, EncBaseId
break;
case Table.TypeRef:
size = GetCodedIndexSize (CodedIndex.ResolutionScope) // ResolutionScope
+ (stridx_size * 2); // Name, Namespace
break;
case Table.TypeDef:
size = 4 // Flags
+ (stridx_size * 2) // Name, Namespace
+ GetCodedIndexSize (CodedIndex.TypeDefOrRef) // BaseType
+ GetTableIndexSize (Table.Field) // FieldList
+ GetTableIndexSize (Table.Method); // MethodList
break;
case Table.FieldPtr:
size = GetTableIndexSize (Table.Field); // Field
break;
case Table.Field:
size = 2 // Flags
+ stridx_size // Name
+ blobidx_size; // Signature
break;
case Table.MethodPtr:
size = GetTableIndexSize (Table.Method); // Method
break;
case Table.Method:
size = 8 // Rva 4, ImplFlags 2, Flags 2
+ stridx_size // Name
+ blobidx_size // Signature
+ GetTableIndexSize (Table.Param); // ParamList
break;
case Table.ParamPtr:
size = GetTableIndexSize (Table.Param); // Param
break;
case Table.Param:
size = 4 // Flags 2, Sequence 2
+ stridx_size; // Name
break;
case Table.InterfaceImpl:
size = GetTableIndexSize (Table.TypeDef) // Class
+ GetCodedIndexSize (CodedIndex.TypeDefOrRef); // Interface
break;
case Table.MemberRef:
size = GetCodedIndexSize (CodedIndex.MemberRefParent) // Class
+ stridx_size // Name
+ blobidx_size; // Signature
break;
case Table.Constant:
size = 2 // Type
+ GetCodedIndexSize (CodedIndex.HasConstant) // Parent
+ blobidx_size; // Value
break;
case Table.CustomAttribute:
size = GetCodedIndexSize (CodedIndex.HasCustomAttribute) // Parent
+ GetCodedIndexSize (CodedIndex.CustomAttributeType) // Type
+ blobidx_size; // Value
break;
case Table.FieldMarshal:
size = GetCodedIndexSize (CodedIndex.HasFieldMarshal) // Parent
+ blobidx_size; // NativeType
break;
case Table.DeclSecurity:
size = 2 // Action
+ GetCodedIndexSize (CodedIndex.HasDeclSecurity) // Parent
+ blobidx_size; // PermissionSet
break;
case Table.ClassLayout:
size = 6 // PackingSize 2, ClassSize 4
+ GetTableIndexSize (Table.TypeDef); // Parent
break;
case Table.FieldLayout:
size = 4 // Offset
+ GetTableIndexSize (Table.Field); // Field
break;
case Table.StandAloneSig:
size = blobidx_size; // Signature
break;
case Table.EventMap:
size = GetTableIndexSize (Table.TypeDef) // Parent
+ GetTableIndexSize (Table.Event); // EventList
break;
case Table.EventPtr:
size = GetTableIndexSize (Table.Event); // Event
break;
case Table.Event:
size = 2 // Flags
+ stridx_size // Name
+ GetCodedIndexSize (CodedIndex.TypeDefOrRef); // EventType
break;
case Table.PropertyMap:
size = GetTableIndexSize (Table.TypeDef) // Parent
+ GetTableIndexSize (Table.Property); // PropertyList
break;
case Table.PropertyPtr:
size = GetTableIndexSize (Table.Property); // Property
break;
case Table.Property:
size = 2 // Flags
+ stridx_size // Name
+ blobidx_size; // Type
break;
case Table.MethodSemantics:
size = 2 // Semantics
+ GetTableIndexSize (Table.Method) // Method
+ GetCodedIndexSize (CodedIndex.HasSemantics); // Association
break;
case Table.MethodImpl:
size = GetTableIndexSize (Table.TypeDef) // Class
+ GetCodedIndexSize (CodedIndex.MethodDefOrRef) // MethodBody
+ GetCodedIndexSize (CodedIndex.MethodDefOrRef); // MethodDeclaration
break;
case Table.ModuleRef:
size = stridx_size; // Name
break;
case Table.TypeSpec:
size = blobidx_size; // Signature
break;
case Table.ImplMap:
size = 2 // MappingFlags
+ GetCodedIndexSize (CodedIndex.MemberForwarded) // MemberForwarded
+ stridx_size // ImportName
+ GetTableIndexSize (Table.ModuleRef); // ImportScope
break;
case Table.FieldRVA:
size = 4 // RVA
+ GetTableIndexSize (Table.Field); // Field
break;
case Table.EncLog:
size = 8;
break;
case Table.EncMap:
size = 4;
break;
case Table.Assembly:
size = 16 // HashAlgId 4, Version 4 * 2, Flags 4
+ blobidx_size // PublicKey
+ (stridx_size * 2); // Name, Culture
break;
case Table.AssemblyProcessor:
size = 4; // Processor
break;
case Table.AssemblyOS:
size = 12; // Platform 4, Version 2 * 4
break;
case Table.AssemblyRef:
size = 12 // Version 2 * 4 + Flags 4
+ (blobidx_size * 2) // PublicKeyOrToken, HashValue
+ (stridx_size * 2); // Name, Culture
break;
case Table.AssemblyRefProcessor:
size = 4 // Processor
+ GetTableIndexSize (Table.AssemblyRef); // AssemblyRef
break;
case Table.AssemblyRefOS:
size = 12 // Platform 4, Version 2 * 4
+ GetTableIndexSize (Table.AssemblyRef); // AssemblyRef
break;
case Table.File:
size = 4 // Flags
+ stridx_size // Name
+ blobidx_size; // HashValue
break;
case Table.ExportedType:
size = 8 // Flags 4, TypeDefId 4
+ (stridx_size * 2) // Name, Namespace
+ GetCodedIndexSize (CodedIndex.Implementation); // Implementation
break;
case Table.ManifestResource:
size = 8 // Offset, Flags
+ stridx_size // Name
+ GetCodedIndexSize (CodedIndex.Implementation); // Implementation
break;
case Table.NestedClass:
size = GetTableIndexSize (Table.TypeDef) // NestedClass
+ GetTableIndexSize (Table.TypeDef); // EnclosingClass
break;
case Table.GenericParam:
size = 4 // Number, Flags
+ GetCodedIndexSize (CodedIndex.TypeOrMethodDef) // Owner
+ stridx_size; // Name
break;
case Table.MethodSpec:
size = GetCodedIndexSize (CodedIndex.MethodDefOrRef) // Method
+ blobidx_size; // Instantiation
break;
case Table.GenericParamConstraint:
size = GetTableIndexSize (Table.GenericParam) // Owner
+ GetCodedIndexSize (CodedIndex.TypeDefOrRef); // Constraint
break;
case Table.Document:
size = blobidx_size // Name
+ guididx_size // HashAlgorithm
+ blobidx_size // Hash
+ guididx_size; // Language
break;
case Table.MethodDebugInformation:
size = GetTableIndexSize (Table.Document) // Document
+ blobidx_size; // SequencePoints
break;
case Table.LocalScope:
size = GetTableIndexSize (Table.Method) // Method
+ GetTableIndexSize (Table.ImportScope) // ImportScope
+ GetTableIndexSize (Table.LocalVariable) // VariableList
+ GetTableIndexSize (Table.LocalConstant) // ConstantList
+ 4 * 2; // StartOffset, Length
break;
case Table.LocalVariable:
size = 2 // Attributes
+ 2 // Index
+ stridx_size; // Name
break;
case Table.LocalConstant:
size = stridx_size // Name
+ blobidx_size; // Signature
break;
case Table.ImportScope:
size = GetTableIndexSize (Table.ImportScope) // Parent
+ blobidx_size;
break;
case Table.StateMachineMethod:
size = GetTableIndexSize (Table.Method) // MoveNextMethod
+ GetTableIndexSize (Table.Method); // KickOffMethod
break;
case Table.CustomDebugInformation:
size = GetCodedIndexSize (CodedIndex.HasCustomDebugInformation) // Parent
+ guididx_size // Kind
+ blobidx_size; // Value
break;
default:
throw new NotSupportedException ();
}
tables [i].RowSize = (uint) size;
tables [i].Offset = offset;
offset += (uint) size * tables [i].Length;
}
}
void ReadPdbHeap ()
{
var heap = image.PdbHeap;
var buffer = new ByteBuffer (heap.data);
heap.Id = buffer.ReadBytes (20);
heap.EntryPoint = buffer.ReadUInt32 ();
heap.TypeSystemTables = buffer.ReadInt64 ();
heap.TypeSystemTableRows = new uint [Mixin.TableCount];
for (int i = 0; i < Mixin.TableCount; i++) {
var table = (Table) i;
if (!heap.HasTable (table))
continue;
heap.TypeSystemTableRows [i] = buffer.ReadUInt32 ();
}
}
public static Image ReadImage (Disposable<Stream> stream, string file_name)
{
try {
var reader = new ImageReader (stream, file_name);
reader.ReadImage ();
return reader.image;
} catch (EndOfStreamException e) {
throw new BadImageFormatException (stream.value.GetFileName (), e);
}
}
public static Image ReadPortablePdb (Disposable<Stream> stream, string file_name)
{
try {
var reader = new ImageReader (stream, file_name);
var length = (uint) stream.value.Length;
reader.image.Sections = new[] {
new Section {
PointerToRawData = 0,
SizeOfRawData = length,
VirtualAddress = 0,
VirtualSize = length,
}
};
reader.metadata = new DataDirectory (0, length);
reader.ReadMetadata ();
return reader.image;
} catch (EndOfStreamException e) {
throw new BadImageFormatException (stream.value.GetFileName (), e);
}
}
}
}
}
#endregion
#region Mono.Cecil.PE\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.IO;
#if !READ_ONLY
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
using RVA = System.UInt32;
namespace Mono.Cecil.PE {
sealed class ImageWriter : BinaryStreamWriter {
readonly ModuleDefinition module;
readonly MetadataBuilder metadata;
readonly TextMap text_map;
readonly internal Disposable<Stream> stream;
readonly string runtime_version;
ImageDebugHeader debug_header;
ByteBuffer win32_resources;
const uint pe_header_size = 0x98u;
const uint section_header_size = 0x28u;
const uint file_alignment = 0x200;
const uint section_alignment = 0x2000;
const ulong image_base = 0x00400000;
internal const RVA text_rva = 0x2000;
readonly bool pe64;
readonly bool has_reloc;
internal Section text;
internal Section rsrc;
internal Section reloc;
ushort sections;
ImageWriter (ModuleDefinition module, string runtime_version, MetadataBuilder metadata, Disposable<Stream> stream, bool metadataOnly = false)
: base (stream.value)
{
this.module = module;
this.runtime_version = runtime_version;
this.text_map = metadata.text_map;
this.stream = stream;
this.metadata = metadata;
if (metadataOnly)
return;
this.pe64 = module.Architecture == TargetArchitecture.AMD64 || module.Architecture == TargetArchitecture.IA64 || module.Architecture == TargetArchitecture.ARM64;
this.has_reloc = module.Architecture == TargetArchitecture.I386;
this.GetDebugHeader ();
this.GetWin32Resources ();
this.BuildTextMap ();
this.sections = (ushort) (has_reloc ? 2 : 1); // text + reloc?
}
void GetDebugHeader ()
{
var symbol_writer = metadata.symbol_writer;
if (symbol_writer != null)
debug_header = symbol_writer.GetDebugHeader ();
if (module.HasDebugHeader) {
var header = module.GetDebugHeader ();
var deterministic = header.GetDeterministicEntry ();
if (deterministic == null)
return;
debug_header = debug_header.AddDeterministicEntry ();
}
}
void GetWin32Resources ()
{
if (!module.HasImage)
return;
DataDirectory win32_resources_directory = module.Image.Win32Resources;
var size = win32_resources_directory.Size;
if (size > 0) {
win32_resources = module.Image.GetReaderAt (win32_resources_directory.VirtualAddress, size, (s, reader) => new ByteBuffer (reader.ReadBytes ((int) s)));
}
}
public static ImageWriter CreateWriter (ModuleDefinition module, MetadataBuilder metadata, Disposable<Stream> stream)
{
var writer = new ImageWriter (module, module.runtime_version, metadata, stream);
writer.BuildSections ();
return writer;
}
public static ImageWriter CreateDebugWriter (ModuleDefinition module, MetadataBuilder metadata, Disposable<Stream> stream)
{
var writer = new ImageWriter (module, "PDB v1.0", metadata, stream, metadataOnly: true);
var length = metadata.text_map.GetLength ();
writer.text = new Section { SizeOfRawData = length, VirtualSize = length };
return writer;
}
void BuildSections ()
{
var has_win32_resources = win32_resources != null;
if (has_win32_resources)
sections++;
text = CreateSection (".text", text_map.GetLength (), null);
var previous = text;
if (has_win32_resources) {
rsrc = CreateSection (".rsrc", (uint) win32_resources.length, previous);
PatchWin32Resources (win32_resources);
previous = rsrc;
}
if (has_reloc)
reloc = CreateSection (".reloc", 12u, previous);
}
Section CreateSection (string name, uint size, Section previous)
{
return new Section {
Name = name,
VirtualAddress = previous != null
? previous.VirtualAddress + Align (previous.VirtualSize, section_alignment)
: text_rva,
VirtualSize = size,
PointerToRawData = previous != null
? previous.PointerToRawData + previous.SizeOfRawData
: Align (GetHeaderSize (), file_alignment),
SizeOfRawData = Align (size, file_alignment)
};
}
static uint Align (uint value, uint align)
{
align--;
return (value + align) & ~align;
}
void WriteDOSHeader ()
{
Write (new byte [] {
// dos header start
0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00,
0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
// lfanew
0x80, 0x00, 0x00, 0x00,
// dos header end
0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09,
0xcd, 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21,
0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72,
0x6f, 0x67, 0x72, 0x61, 0x6d, 0x20, 0x63,
0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62,
0x65, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x69,
0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, 0x6d,
0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a,
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00
});
}
ushort SizeOfOptionalHeader ()
{
return (ushort) (!pe64 ? 0xe0 : 0xf0);
}
void WritePEFileHeader ()
{
WriteUInt32 (0x00004550); // Magic
WriteUInt16 ((ushort) module.Architecture); // Machine
WriteUInt16 (sections); // NumberOfSections
WriteUInt32 (metadata.timestamp);
WriteUInt32 (0); // PointerToSymbolTable
WriteUInt32 (0); // NumberOfSymbols
WriteUInt16 (SizeOfOptionalHeader ()); // SizeOfOptionalHeader
// ExecutableImage | (pe64 ? 32BitsMachine : LargeAddressAware)
var characteristics = (ushort) (0x0002 | (!pe64 ? 0x0100 : 0x0020));
if (module.Kind == ModuleKind.Dll || module.Kind == ModuleKind.NetModule)
characteristics |= 0x2000;
WriteUInt16 (characteristics); // Characteristics
}
Section LastSection ()
{
if (reloc != null)
return reloc;
if (rsrc != null)
return rsrc;
return text;
}
void WriteOptionalHeaders ()
{
WriteUInt16 ((ushort) (!pe64 ? 0x10b : 0x20b)); // Magic
WriteUInt16 (module.linker_version);
WriteUInt32 (text.SizeOfRawData); // CodeSize
WriteUInt32 ((reloc != null ? reloc.SizeOfRawData : 0)
+ (rsrc != null ? rsrc.SizeOfRawData : 0)); // InitializedDataSize
WriteUInt32 (0); // UninitializedDataSize
var startub_stub = text_map.GetRange (TextSegment.StartupStub);
WriteUInt32 (startub_stub.Length > 0 ? startub_stub.Start : 0); // EntryPointRVA
WriteUInt32 (text_rva); // BaseOfCode
if (!pe64) {
WriteUInt32 (0); // BaseOfData
WriteUInt32 ((uint) image_base); // ImageBase
} else {
WriteUInt64 (image_base); // ImageBase
}
WriteUInt32 (section_alignment); // SectionAlignment
WriteUInt32 (file_alignment); // FileAlignment
WriteUInt16 (4); // OSMajor
WriteUInt16 (0); // OSMinor
WriteUInt16 (0); // UserMajor
WriteUInt16 (0); // UserMinor
WriteUInt16 (4); // SubSysMajor
WriteUInt16 (0); // SubSysMinor
WriteUInt32 (0); // Reserved
var last_section = LastSection();
WriteUInt32 (last_section.VirtualAddress + Align (last_section.VirtualSize, section_alignment)); // ImageSize
WriteUInt32 (text.PointerToRawData); // HeaderSize
WriteUInt32 (0); // Checksum
WriteUInt16 (GetSubSystem ()); // SubSystem
WriteUInt16 ((ushort) module.Characteristics); // DLLFlags
const ulong stack_reserve = 0x100000;
const ulong stack_commit = 0x1000;
const ulong heap_reserve = 0x100000;
const ulong heap_commit = 0x1000;
if (!pe64) {
WriteUInt32 ((uint) stack_reserve);
WriteUInt32 ((uint) stack_commit);
WriteUInt32 ((uint) heap_reserve);
WriteUInt32 ((uint) heap_commit);
} else {
WriteUInt64 (stack_reserve);
WriteUInt64 (stack_commit);
WriteUInt64 (heap_reserve);
WriteUInt64 (heap_commit);
}
WriteUInt32 (0); // LoaderFlags
WriteUInt32 (16); // NumberOfDataDir
WriteZeroDataDirectory (); // ExportTable
WriteDataDirectory (text_map.GetDataDirectory (TextSegment.ImportDirectory)); // ImportTable
if (rsrc != null) { // ResourceTable
WriteUInt32 (rsrc.VirtualAddress);
WriteUInt32 (rsrc.VirtualSize);
} else
WriteZeroDataDirectory ();
WriteZeroDataDirectory (); // ExceptionTable
WriteZeroDataDirectory (); // CertificateTable
WriteUInt32 (reloc != null ? reloc.VirtualAddress : 0); // BaseRelocationTable
WriteUInt32 (reloc != null ? reloc.VirtualSize : 0);
if (text_map.GetLength (TextSegment.DebugDirectory) > 0) {
WriteUInt32 (text_map.GetRVA (TextSegment.DebugDirectory));
WriteUInt32 ((uint) (debug_header.Entries.Length * ImageDebugDirectory.Size));
} else
WriteZeroDataDirectory ();
WriteZeroDataDirectory (); // Copyright
WriteZeroDataDirectory (); // GlobalPtr
WriteZeroDataDirectory (); // TLSTable
WriteZeroDataDirectory (); // LoadConfigTable
WriteZeroDataDirectory (); // BoundImport
WriteDataDirectory (text_map.GetDataDirectory (TextSegment.ImportAddressTable)); // IAT
WriteZeroDataDirectory (); // DelayImportDesc
WriteDataDirectory (text_map.GetDataDirectory (TextSegment.CLIHeader)); // CLIHeader
WriteZeroDataDirectory (); // Reserved
}
void WriteZeroDataDirectory ()
{
WriteUInt32 (0);
WriteUInt32 (0);
}
ushort GetSubSystem ()
{
switch (module.Kind) {
case ModuleKind.Console:
case ModuleKind.Dll:
case ModuleKind.NetModule:
return 0x3;
case ModuleKind.Windows:
return 0x2;
default:
throw new ArgumentOutOfRangeException ();
}
}
void WriteSectionHeaders ()
{
WriteSection (text, 0x60000020);
if (rsrc != null)
WriteSection (rsrc, 0x40000040);
if (reloc != null)
WriteSection (reloc, 0x42000040);
}
void WriteSection (Section section, uint characteristics)
{
var name = new byte [8];
var sect_name = section.Name;
for (int i = 0; i < sect_name.Length; i++)
name [i] = (byte) sect_name [i];
WriteBytes (name);
WriteUInt32 (section.VirtualSize);
WriteUInt32 (section.VirtualAddress);
WriteUInt32 (section.SizeOfRawData);
WriteUInt32 (section.PointerToRawData);
WriteUInt32 (0); // PointerToRelocations
WriteUInt32 (0); // PointerToLineNumbers
WriteUInt16 (0); // NumberOfRelocations
WriteUInt16 (0); // NumberOfLineNumbers
WriteUInt32 (characteristics);
}
void MoveTo (uint pointer)
{
BaseStream.Seek (pointer, SeekOrigin.Begin);
}
void MoveToRVA (Section section, RVA rva)
{
BaseStream.Seek (section.PointerToRawData + rva - section.VirtualAddress, SeekOrigin.Begin);
}
void MoveToRVA (TextSegment segment)
{
MoveToRVA (text, text_map.GetRVA (segment));
}
void WriteRVA (RVA rva)
{
if (!pe64)
WriteUInt32 (rva);
else
WriteUInt64 (rva);
}
void PrepareSection (Section section)
{
MoveTo (section.PointerToRawData);
const int buffer_size = 4096;
if (section.SizeOfRawData <= buffer_size) {
Write (new byte [section.SizeOfRawData]);
MoveTo (section.PointerToRawData);
return;
}
var written = 0;
var buffer = new byte [buffer_size];
while (written != section.SizeOfRawData) {
var write_size = System.Math.Min((int) section.SizeOfRawData - written, buffer_size);
Write (buffer, 0, write_size);
written += write_size;
}
MoveTo (section.PointerToRawData);
}
void WriteText ()
{
PrepareSection (text);
// ImportAddressTable
if (has_reloc) {
WriteRVA (text_map.GetRVA (TextSegment.ImportHintNameTable));
WriteRVA (0);
}
// CLIHeader
WriteUInt32 (0x48);
WriteUInt16 (2);
WriteUInt16 ((ushort) ((module.Runtime <= TargetRuntime.Net_1_1) ? 0 : 5));
WriteUInt32 (text_map.GetRVA (TextSegment.MetadataHeader));
WriteUInt32 (GetMetadataLength ());
WriteUInt32 ((uint) module.Attributes);
WriteUInt32 (metadata.entry_point.ToUInt32 ());
WriteDataDirectory (text_map.GetDataDirectory (TextSegment.Resources));
WriteDataDirectory (text_map.GetDataDirectory (TextSegment.StrongNameSignature));
WriteZeroDataDirectory (); // CodeManagerTable
WriteZeroDataDirectory (); // VTableFixups
WriteZeroDataDirectory (); // ExportAddressTableJumps
WriteZeroDataDirectory (); // ManagedNativeHeader
// Code
MoveToRVA (TextSegment.Code);
WriteBuffer (metadata.code);
// Resources
MoveToRVA (TextSegment.Resources);
WriteBuffer (metadata.resources);
// Data
if (metadata.data.length > 0) {
MoveToRVA (TextSegment.Data);
WriteBuffer (metadata.data);
}
// StrongNameSignature
// stays blank
// MetadataHeader
MoveToRVA (TextSegment.MetadataHeader);
WriteMetadataHeader ();
WriteMetadata ();
// DebugDirectory
if (text_map.GetLength (TextSegment.DebugDirectory) > 0) {
MoveToRVA (TextSegment.DebugDirectory);
WriteDebugDirectory ();
}
if (!has_reloc)
return;
// ImportDirectory
MoveToRVA (TextSegment.ImportDirectory);
WriteImportDirectory ();
// StartupStub
MoveToRVA (TextSegment.StartupStub);
WriteStartupStub ();
}
uint GetMetadataLength ()
{
return text_map.GetRVA (TextSegment.DebugDirectory) - text_map.GetRVA (TextSegment.MetadataHeader);
}
public void WriteMetadataHeader ()
{
WriteUInt32 (0x424a5342); // Signature
WriteUInt16 (1); // MajorVersion
WriteUInt16 (1); // MinorVersion
WriteUInt32 (0); // Reserved
var version = GetZeroTerminatedString (runtime_version);
WriteUInt32 ((uint) version.Length);
WriteBytes (version);
WriteUInt16 (0); // Flags
WriteUInt16 (GetStreamCount ());
uint offset = text_map.GetRVA (TextSegment.TableHeap) - text_map.GetRVA (TextSegment.MetadataHeader);
WriteStreamHeader (ref offset, TextSegment.TableHeap, "#~");
WriteStreamHeader (ref offset, TextSegment.StringHeap, "#Strings");
WriteStreamHeader (ref offset, TextSegment.UserStringHeap, "#US");
WriteStreamHeader (ref offset, TextSegment.GuidHeap, "#GUID");
WriteStreamHeader (ref offset, TextSegment.BlobHeap, "#Blob");
WriteStreamHeader (ref offset, TextSegment.PdbHeap, "#Pdb");
}
ushort GetStreamCount ()
{
return (ushort) (
1 // #~
+ 1 // #Strings
+ (metadata.user_string_heap.IsEmpty ? 0 : 1) // #US
+ (metadata.guid_heap.IsEmpty ? 0 : 1) // GUID
+ (metadata.blob_heap.IsEmpty ? 0 : 1)
+ (metadata.pdb_heap == null ? 0 : 1)); // #Blob
}
void WriteStreamHeader (ref uint offset, TextSegment heap, string name)
{
var length = (uint) text_map.GetLength (heap);
if (length == 0)
return;
WriteUInt32 (offset);
WriteUInt32 (length);
WriteBytes (GetZeroTerminatedString (name));
offset += length;
}
static int GetZeroTerminatedStringLength (string @string)
{
return (@string.Length + 1 + 3) & ~3;
}
static byte [] GetZeroTerminatedString (string @string)
{
return GetString (@string, GetZeroTerminatedStringLength (@string));
}
static byte [] GetSimpleString (string @string)
{
return GetString (@string, @string.Length);
}
static byte [] GetString (string @string, int length)
{
var bytes = new byte [length];
for (int i = 0; i < @string.Length; i++)
bytes [i] = (byte) @string [i];
return bytes;
}
public void WriteMetadata ()
{
WriteHeap (TextSegment.TableHeap, metadata.table_heap);
WriteHeap (TextSegment.StringHeap, metadata.string_heap);
WriteHeap (TextSegment.UserStringHeap, metadata.user_string_heap);
WriteHeap (TextSegment.GuidHeap, metadata.guid_heap);
WriteHeap (TextSegment.BlobHeap, metadata.blob_heap);
WriteHeap (TextSegment.PdbHeap, metadata.pdb_heap);
}
void WriteHeap (TextSegment heap, HeapBuffer buffer)
{
if (buffer == null || buffer.IsEmpty)
return;
MoveToRVA (heap);
WriteBuffer (buffer);
}
void WriteDebugDirectory ()
{
var data_start = (int) BaseStream.Position + (debug_header.Entries.Length * ImageDebugDirectory.Size);
for (var i = 0; i < debug_header.Entries.Length; i++) {
var entry = debug_header.Entries [i];
var directory = entry.Directory;
WriteInt32 (directory.Characteristics);
WriteInt32 (directory.TimeDateStamp);
WriteInt16 (directory.MajorVersion);
WriteInt16 (directory.MinorVersion);
WriteInt32 ((int) directory.Type);
WriteInt32 (directory.SizeOfData);
WriteInt32 (directory.AddressOfRawData);
WriteInt32 (data_start);
data_start += entry.Data.Length;
}
for (var i = 0; i < debug_header.Entries.Length; i++) {
var entry = debug_header.Entries [i];
WriteBytes (entry.Data);
}
}
void WriteImportDirectory ()
{
WriteUInt32 (text_map.GetRVA (TextSegment.ImportDirectory) + 40); // ImportLookupTable
WriteUInt32 (0); // DateTimeStamp
WriteUInt32 (0); // ForwarderChain
WriteUInt32 (text_map.GetRVA (TextSegment.ImportHintNameTable) + 14);
WriteUInt32 (text_map.GetRVA (TextSegment.ImportAddressTable));
Advance (20);
// ImportLookupTable
WriteUInt32 (text_map.GetRVA (TextSegment.ImportHintNameTable));
// ImportHintNameTable
MoveToRVA (TextSegment.ImportHintNameTable);
WriteUInt16 (0); // Hint
WriteBytes (GetRuntimeMain ());
WriteByte (0);
WriteBytes (GetSimpleString ("mscoree.dll"));
WriteUInt16 (0);
}
byte [] GetRuntimeMain ()
{
return module.Kind == ModuleKind.Dll || module.Kind == ModuleKind.NetModule
? GetSimpleString ("_CorDllMain")
: GetSimpleString ("_CorExeMain");
}
void WriteStartupStub ()
{
switch (module.Architecture) {
case TargetArchitecture.I386:
WriteUInt16 (0x25ff);
WriteUInt32 ((uint) image_base + text_map.GetRVA (TextSegment.ImportAddressTable));
return;
default:
throw new NotSupportedException ();
}
}
void WriteRsrc ()
{
PrepareSection (rsrc);
WriteBuffer (win32_resources);
}
void WriteReloc ()
{
PrepareSection (reloc);
var reloc_rva = text_map.GetRVA (TextSegment.StartupStub);
reloc_rva += module.Architecture == TargetArchitecture.IA64 ? 0x20u : 2;
var page_rva = reloc_rva & ~0xfffu;
WriteUInt32 (page_rva); // PageRVA
WriteUInt32 (0x000c); // Block Size
switch (module.Architecture) {
case TargetArchitecture.I386:
WriteUInt32 (0x3000 + reloc_rva - page_rva);
break;
default:
throw new NotSupportedException();
}
}
public void WriteImage ()
{
WriteDOSHeader ();
WritePEFileHeader ();
WriteOptionalHeaders ();
WriteSectionHeaders ();
WriteText ();
if (rsrc != null)
WriteRsrc ();
if (reloc != null)
WriteReloc ();
Flush ();
}
void BuildTextMap ()
{
var map = text_map;
map.AddMap (TextSegment.Code, metadata.code.length, !pe64 ? 4 : 16);
map.AddMap (TextSegment.Resources, metadata.resources.length, 8);
map.AddMap (TextSegment.Data, metadata.data.length, 4);
if (metadata.data.length > 0)
metadata.table_heap.FixupData (map.GetRVA (TextSegment.Data));
map.AddMap (TextSegment.StrongNameSignature, GetStrongNameLength (), 4);
BuildMetadataTextMap ();
int debug_dir_len = 0;
if (debug_header != null && debug_header.HasEntries) {
var directories_len = debug_header.Entries.Length * ImageDebugDirectory.Size;
var data_address = (int) map.GetNextRVA (TextSegment.BlobHeap) + directories_len;
var data_len = 0;
for (var i = 0; i < debug_header.Entries.Length; i++) {
var entry = debug_header.Entries [i];
var directory = entry.Directory;
directory.AddressOfRawData = entry.Data.Length == 0 ? 0 : data_address;
entry.Directory = directory;
data_len += entry.Data.Length;
data_address += data_len;
}
debug_dir_len = directories_len + data_len;
}
map.AddMap (TextSegment.DebugDirectory, debug_dir_len, 4);
if (!has_reloc) {
var start = map.GetNextRVA (TextSegment.DebugDirectory);
map.AddMap (TextSegment.ImportDirectory, new Range (start, 0));
map.AddMap (TextSegment.ImportHintNameTable, new Range (start, 0));
map.AddMap (TextSegment.StartupStub, new Range (start, 0));
return;
}
RVA import_dir_rva = map.GetNextRVA (TextSegment.DebugDirectory);
RVA import_hnt_rva = import_dir_rva + 48u;
import_hnt_rva = (import_hnt_rva + 15u) & ~15u;
uint import_dir_len = (import_hnt_rva - import_dir_rva) + 27u;
RVA startup_stub_rva = import_dir_rva + import_dir_len;
startup_stub_rva = module.Architecture == TargetArchitecture.IA64
? (startup_stub_rva + 15u) & ~15u
: 2 + ((startup_stub_rva + 3u) & ~3u);
map.AddMap (TextSegment.ImportDirectory, new Range (import_dir_rva, import_dir_len));
map.AddMap (TextSegment.ImportHintNameTable, new Range (import_hnt_rva, 0));
map.AddMap (TextSegment.StartupStub, new Range (startup_stub_rva, GetStartupStubLength ()));
}
public void BuildMetadataTextMap ()
{
var map = text_map;
map.AddMap (TextSegment.MetadataHeader, GetMetadataHeaderLength (module.RuntimeVersion));
map.AddMap (TextSegment.TableHeap, metadata.table_heap.length, 4);
map.AddMap (TextSegment.StringHeap, metadata.string_heap.length, 4);
map.AddMap (TextSegment.UserStringHeap, metadata.user_string_heap.IsEmpty ? 0 : metadata.user_string_heap.length, 4);
map.AddMap (TextSegment.GuidHeap, metadata.guid_heap.length, 4);
map.AddMap (TextSegment.BlobHeap, metadata.blob_heap.IsEmpty ? 0 : metadata.blob_heap.length, 4);
map.AddMap (TextSegment.PdbHeap, metadata.pdb_heap == null ? 0 : metadata.pdb_heap.length, 4);
}
uint GetStartupStubLength ()
{
switch (module.Architecture) {
case TargetArchitecture.I386:
return 6;
default:
throw new NotSupportedException ();
}
}
int GetMetadataHeaderLength (string runtimeVersion)
{
return
// MetadataHeader
20 + GetZeroTerminatedStringLength (runtimeVersion)
// #~ header
+ 12
// #Strings header
+ 20
// #US header
+ (metadata.user_string_heap.IsEmpty ? 0 : 12)
// #GUID header
+ 16
// #Blob header
+ (metadata.blob_heap.IsEmpty ? 0 : 16)
//
+ (metadata.pdb_heap == null ? 0 : 16);
}
int GetStrongNameLength ()
{
if (module.Assembly == null)
return 0;
var public_key = module.Assembly.Name.PublicKey;
if (public_key.IsNullOrEmpty ())
return 0;
// in fx 2.0 the key may be from 384 to 16384 bits
// so we must calculate the signature size based on
// the size of the public key (minus the 32 byte header)
int size = public_key.Length;
if (size > 32)
return size - 32;
// note: size == 16 for the ECMA "key" which is replaced
// by the runtime with a 1024 bits key (128 bytes)
return 128; // default strongname signature size
}
public DataDirectory GetStrongNameSignatureDirectory ()
{
return text_map.GetDataDirectory (TextSegment.StrongNameSignature);
}
public uint GetHeaderSize ()
{
return pe_header_size + SizeOfOptionalHeader () + (sections * section_header_size);
}
void PatchWin32Resources (ByteBuffer resources)
{
PatchResourceDirectoryTable (resources);
}
void PatchResourceDirectoryTable (ByteBuffer resources)
{
resources.Advance (12);
var entries = resources.ReadUInt16 () + resources.ReadUInt16 ();
for (int i = 0; i < entries; i++)
PatchResourceDirectoryEntry (resources);
}
void PatchResourceDirectoryEntry (ByteBuffer resources)
{
resources.Advance (4);
var child = resources.ReadUInt32 ();
var position = resources.position;
resources.position = (int) child & 0x7fffffff;
if ((child & 0x80000000) != 0)
PatchResourceDirectoryTable (resources);
else
PatchResourceDataEntry (resources);
resources.position = position;
}
void PatchResourceDataEntry (ByteBuffer resources)
{
var rva = resources.ReadUInt32 ();
resources.position -= 4;
resources.WriteUInt32 (rva - module.Image.Win32Resources.VirtualAddress + rsrc.VirtualAddress);
}
}
}
#endif
}
#endregion
#region Mono.Cecil.PE\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using RVA = System.UInt32;
namespace Mono.Cecil.PE {
sealed class Section {
public string Name;
public RVA VirtualAddress;
public uint VirtualSize;
public uint SizeOfRawData;
public uint PointerToRawData;
}
}
}
#endregion
#region Mono.Cecil.PE\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
#if !READ_ONLY
using RVA = System.UInt32;
namespace Mono.Cecil.PE {
enum TextSegment {
ImportAddressTable,
CLIHeader,
Code,
Resources,
Data,
StrongNameSignature,
// Metadata
MetadataHeader,
TableHeap,
StringHeap,
UserStringHeap,
GuidHeap,
BlobHeap,
PdbHeap,
// End Metadata
DebugDirectory,
ImportDirectory,
ImportHintNameTable,
StartupStub,
}
sealed class TextMap {
readonly Range [] map = new Range [17 /*Enum.GetValues (typeof (TextSegment)).Length*/];
public void AddMap (TextSegment segment, int length)
{
map [(int) segment] = new Range (GetStart (segment), (uint) length);
}
public void AddMap (TextSegment segment, int length, int align)
{
align--;
AddMap (segment, (length + align) & ~align);
}
public void AddMap (TextSegment segment, Range range)
{
map [(int) segment] = range;
}
public Range GetRange (TextSegment segment)
{
return map [(int) segment];
}
public DataDirectory GetDataDirectory (TextSegment segment)
{
var range = map [(int) segment];
return new DataDirectory (range.Length == 0 ? 0 : range.Start, range.Length);
}
public RVA GetRVA (TextSegment segment)
{
return map [(int) segment].Start;
}
public RVA GetNextRVA (TextSegment segment)
{
var i = (int) segment;
return map [i].Start + map [i].Length;
}
public int GetLength (TextSegment segment)
{
return (int) map [(int) segment].Length;
}
RVA GetStart (TextSegment segment)
{
var index = (int) segment;
return index == 0 ? ImageWriter.text_rva : ComputeStart (index);
}
RVA ComputeStart (int index)
{
index--;
return map [index].Start + map [index].Length;
}
public uint GetLength ()
{
var range = map [(int) TextSegment.StartupStub];
return range.Start - ImageWriter.text_rva + range.Length;
}
}
}
#endif
}
#endregion
#region Mono.Collections.Generic\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Collections;
using System.Collections.Generic;
using Mono.Cecil;
namespace Mono.Collections.Generic {
internal class Collection<T> : IList<T>, IList {
internal T [] items;
internal int size;
int version;
public int Count {
get { return size; }
}
public T this [int index] {
get {
if (index >= size)
throw new ArgumentOutOfRangeException ();
return items [index];
}
set {
CheckIndex (index);
if (index == size)
throw new ArgumentOutOfRangeException ();
OnSet (value, index);
items [index] = value;
}
}
public int Capacity {
get { return items.Length; }
set {
if (value < 0 || value < size)
throw new ArgumentOutOfRangeException ();
Resize (value);
}
}
bool ICollection<T>.IsReadOnly {
get { return false; }
}
bool IList.IsFixedSize {
get { return false; }
}
bool IList.IsReadOnly {
get { return false; }
}
object IList.this [int index] {
get { return this [index]; }
set {
CheckIndex (index);
try {
this [index] = (T) value;
return;
} catch (InvalidCastException) {
} catch (NullReferenceException) {
}
throw new ArgumentException ();
}
}
int ICollection.Count {
get { return Count; }
}
bool ICollection.IsSynchronized {
get { return false; }
}
object ICollection.SyncRoot {
get { return this; }
}
public Collection ()
{
items = Empty<T>.Array;
}
public Collection (int capacity)
{
if (capacity < 0)
throw new ArgumentOutOfRangeException ();
items = new T [capacity];
}
public Collection (ICollection<T> items)
{
if (items == null)
throw new ArgumentNullException ("items");
this.items = new T [items.Count];
items.CopyTo (this.items, 0);
this.size = this.items.Length;
}
public void Add (T item)
{
if (size == items.Length)
Grow (1);
OnAdd (item, size);
items [size++] = item;
version++;
}
public bool Contains (T item)
{
return IndexOf (item) != -1;
}
public int IndexOf (T item)
{
return Array.IndexOf (items, item, 0, size);
}
public void Insert (int index, T item)
{
CheckIndex (index);
if (size == items.Length)
Grow (1);
OnInsert (item, index);
Shift (index, 1);
items [index] = item;
version++;
}
public void RemoveAt (int index)
{
if (index < 0 || index >= size)
throw new ArgumentOutOfRangeException ();
var item = items [index];
OnRemove (item, index);
Shift (index, -1);
version++;
}
public bool Remove (T item)
{
var index = IndexOf (item);
if (index == -1)
return false;
OnRemove (item, index);
Shift (index, -1);
version++;
return true;
}
public void Clear ()
{
OnClear ();
Array.Clear (items, 0, size);
size = 0;
version++;
}
public void CopyTo (T [] array, int arrayIndex)
{
Array.Copy (items, 0, array, arrayIndex, size);
}
public T [] ToArray ()
{
var array = new T [size];
Array.Copy (items, 0, array, 0, size);
return array;
}
void CheckIndex (int index)
{
if (index < 0 || index > size)
throw new ArgumentOutOfRangeException ();
}
void Shift (int start, int delta)
{
if (delta < 0)
start -= delta;
if (start < size)
Array.Copy (items, start, items, start + delta, size - start);
size += delta;
if (delta < 0)
Array.Clear (items, size, -delta);
}
protected virtual void OnAdd (T item, int index)
{
}
protected virtual void OnInsert (T item, int index)
{
}
protected virtual void OnSet (T item, int index)
{
}
protected virtual void OnRemove (T item, int index)
{
}
protected virtual void OnClear ()
{
}
internal virtual void Grow (int desired)
{
int new_size = size + desired;
if (new_size <= items.Length)
return;
const int default_capacity = 4;
new_size = System.Math.Max (
System.Math.Max (items.Length * 2, default_capacity),
new_size);
Resize (new_size);
}
protected void Resize (int new_size)
{
if (new_size == size)
return;
if (new_size < size)
throw new ArgumentOutOfRangeException ();
items = items.Resize (new_size);
}
int IList.Add (object value)
{
try {
Add ((T) value);
return size - 1;
} catch (InvalidCastException) {
} catch (NullReferenceException) {
}
throw new ArgumentException ();
}
void IList.Clear ()
{
Clear ();
}
bool IList.Contains (object value)
{
return ((IList) this).IndexOf (value) > -1;
}
int IList.IndexOf (object value)
{
try {
return IndexOf ((T) value);
} catch (InvalidCastException) {
} catch (NullReferenceException) {
}
return -1;
}
void IList.Insert (int index, object value)
{
CheckIndex (index);
try {
Insert (index, (T) value);
return;
} catch (InvalidCastException) {
} catch (NullReferenceException) {
}
throw new ArgumentException ();
}
void IList.Remove (object value)
{
try {
Remove ((T) value);
} catch (InvalidCastException) {
} catch (NullReferenceException) {
}
}
void IList.RemoveAt (int index)
{
RemoveAt (index);
}
void ICollection.CopyTo (Array array, int index)
{
Array.Copy (items, 0, array, index, size);
}
public Enumerator GetEnumerator ()
{
return new Enumerator (this);
}
IEnumerator IEnumerable.GetEnumerator ()
{
return new Enumerator (this);
}
IEnumerator<T> IEnumerable<T>.GetEnumerator ()
{
return new Enumerator (this);
}
internal struct Enumerator : IEnumerator<T>, IDisposable {
Collection<T> collection;
T current;
int next;
readonly int version;
public T Current {
get { return current; }
}
object IEnumerator.Current {
get {
CheckState ();
if (next <= 0)
throw new InvalidOperationException ();
return current;
}
}
internal Enumerator (Collection<T> collection)
: this ()
{
this.collection = collection;
this.version = collection.version;
}
public bool MoveNext ()
{
CheckState ();
if (next < 0)
return false;
if (next < collection.size) {
current = collection.items [next++];
return true;
}
next = -1;
return false;
}
public void Reset ()
{
CheckState ();
next = 0;
}
void CheckState ()
{
if (collection == null)
throw new ObjectDisposedException (GetType ().FullName);
if (version != collection.version)
throw new InvalidOperationException ();
}
public void Dispose ()
{
collection = null;
}
}
}
}
}
#endregion
#region Mono.Collections.Generic\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
using System;
using System.Collections;
using System.Collections.Generic;
namespace Mono.Collections.Generic {
internal sealed class ReadOnlyCollection<T> : Collection<T>, ICollection<T>, IList {
static ReadOnlyCollection<T> empty;
public static ReadOnlyCollection<T> Empty {
get { return empty ?? (empty = new ReadOnlyCollection<T> ()); }
}
bool ICollection<T>.IsReadOnly {
get { return true; }
}
bool IList.IsFixedSize {
get { return true; }
}
bool IList.IsReadOnly {
get { return true; }
}
ReadOnlyCollection ()
{
}
public ReadOnlyCollection (T [] array)
{
if (array == null)
throw new ArgumentNullException ();
Initialize (array, array.Length);
}
public ReadOnlyCollection (Collection<T> collection)
{
if (collection == null)
throw new ArgumentNullException ();
Initialize (collection.items, collection.size);
}
void Initialize (T [] items, int size)
{
this.items = new T [size];
Array.Copy (items, 0, this.items, 0, size);
this.size = size;
}
internal override void Grow (int desired)
{
throw new InvalidOperationException ();
}
protected override void OnAdd (T item, int index)
{
throw new InvalidOperationException ();
}
protected override void OnClear ()
{
throw new InvalidOperationException ();
}
protected override void OnInsert (T item, int index)
{
throw new InvalidOperationException ();
}
protected override void OnRemove (T item, int index)
{
throw new InvalidOperationException ();
}
protected override void OnSet (T item, int index)
{
throw new InvalidOperationException ();
}
}
}
}
#endregion
#region Mono.Security.Cryptography\*.cs
namespace Internal {
//
// CryptoConvert.cs - Crypto Convertion Routines
//
// Author:
// Sebastien Pouliot <sebastien@ximian.com>
//
// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
// Copyright (C) 2004-2006 Novell Inc. (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if !READ_ONLY
#if !NET_CORE
using System;
using System.Security.Cryptography;
namespace Mono.Security.Cryptography {
static class CryptoConvert {
static private int ToInt32LE (byte [] bytes, int offset)
{
return (bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset];
}
static private uint ToUInt32LE (byte [] bytes, int offset)
{
return (uint)((bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset]);
}
static private byte[] Trim (byte[] array)
{
for (int i=0; i < array.Length; i++) {
if (array [i] != 0x00) {
byte[] result = new byte [array.Length - i];
Buffer.BlockCopy (array, i, result, 0, result.Length);
return result;
}
}
return null;
}
static RSA FromCapiPrivateKeyBlob (byte[] blob, int offset)
{
RSAParameters rsap = new RSAParameters ();
try {
if ((blob [offset] != 0x07) || // PRIVATEKEYBLOB (0x07)
(blob [offset+1] != 0x02) || // Version (0x02)
(blob [offset+2] != 0x00) || // Reserved (word)
(blob [offset+3] != 0x00) ||
(ToUInt32LE (blob, offset+8) != 0x32415352)) // DWORD magic = RSA2
throw new CryptographicException ("Invalid blob header");
// ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...)
// int algId = ToInt32LE (blob, offset+4);
// DWORD bitlen
int bitLen = ToInt32LE (blob, offset+12);
// DWORD public exponent
byte[] exp = new byte [4];
Buffer.BlockCopy (blob, offset+16, exp, 0, 4);
Array.Reverse (exp);
rsap.Exponent = Trim (exp);
int pos = offset+20;
// BYTE modulus[rsapubkey.bitlen/8];
int byteLen = (bitLen >> 3);
rsap.Modulus = new byte [byteLen];
Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen);
Array.Reverse (rsap.Modulus);
pos += byteLen;
// BYTE prime1[rsapubkey.bitlen/16];
int byteHalfLen = (byteLen >> 1);
rsap.P = new byte [byteHalfLen];
Buffer.BlockCopy (blob, pos, rsap.P, 0, byteHalfLen);
Array.Reverse (rsap.P);
pos += byteHalfLen;
// BYTE prime2[rsapubkey.bitlen/16];
rsap.Q = new byte [byteHalfLen];
Buffer.BlockCopy (blob, pos, rsap.Q, 0, byteHalfLen);
Array.Reverse (rsap.Q);
pos += byteHalfLen;
// BYTE exponent1[rsapubkey.bitlen/16];
rsap.DP = new byte [byteHalfLen];
Buffer.BlockCopy (blob, pos, rsap.DP, 0, byteHalfLen);
Array.Reverse (rsap.DP);
pos += byteHalfLen;
// BYTE exponent2[rsapubkey.bitlen/16];
rsap.DQ = new byte [byteHalfLen];
Buffer.BlockCopy (blob, pos, rsap.DQ, 0, byteHalfLen);
Array.Reverse (rsap.DQ);
pos += byteHalfLen;
// BYTE coefficient[rsapubkey.bitlen/16];
rsap.InverseQ = new byte [byteHalfLen];
Buffer.BlockCopy (blob, pos, rsap.InverseQ, 0, byteHalfLen);
Array.Reverse (rsap.InverseQ);
pos += byteHalfLen;
// ok, this is hackish but CryptoAPI support it so...
// note: only works because CRT is used by default
// http://bugzilla.ximian.com/show_bug.cgi?id=57941
rsap.D = new byte [byteLen]; // must be allocated
if (pos + byteLen + offset <= blob.Length) {
// BYTE privateExponent[rsapubkey.bitlen/8];
Buffer.BlockCopy (blob, pos, rsap.D, 0, byteLen);
Array.Reverse (rsap.D);
}
}
catch (Exception e) {
throw new CryptographicException ("Invalid blob.", e);
}
RSA rsa = null;
try {
rsa = RSA.Create ();
rsa.ImportParameters (rsap);
}
catch (CryptographicException) {
// this may cause problem when this code is run under
// the SYSTEM identity on Windows (e.g. ASP.NET). See
// http://bugzilla.ximian.com/show_bug.cgi?id=77559
bool throws = false;
try {
CspParameters csp = new CspParameters ();
csp.Flags = CspProviderFlags.UseMachineKeyStore;
rsa = new RSACryptoServiceProvider (csp);
rsa.ImportParameters (rsap);
}
catch {
throws = true;
}
if (throws) {
// rethrow original, not the latter, exception if this fails
throw;
}
}
return rsa;
}
static RSA FromCapiPublicKeyBlob (byte[] blob, int offset)
{
try {
if ((blob [offset] != 0x06) || // PUBLICKEYBLOB (0x06)
(blob [offset+1] != 0x02) || // Version (0x02)
(blob [offset+2] != 0x00) || // Reserved (word)
(blob [offset+3] != 0x00) ||
(ToUInt32LE (blob, offset+8) != 0x31415352)) // DWORD magic = RSA1
throw new CryptographicException ("Invalid blob header");
// ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...)
// int algId = ToInt32LE (blob, offset+4);
// DWORD bitlen
int bitLen = ToInt32LE (blob, offset+12);
// DWORD public exponent
RSAParameters rsap = new RSAParameters ();
rsap.Exponent = new byte [3];
rsap.Exponent [0] = blob [offset+18];
rsap.Exponent [1] = blob [offset+17];
rsap.Exponent [2] = blob [offset+16];
int pos = offset+20;
// BYTE modulus[rsapubkey.bitlen/8];
int byteLen = (bitLen >> 3);
rsap.Modulus = new byte [byteLen];
Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen);
Array.Reverse (rsap.Modulus);
RSA rsa = null;
try {
rsa = RSA.Create ();
rsa.ImportParameters (rsap);
}
catch (CryptographicException) {
// this may cause problem when this code is run under
// the SYSTEM identity on Windows (e.g. ASP.NET). See
// http://bugzilla.ximian.com/show_bug.cgi?id=77559
CspParameters csp = new CspParameters ();
csp.Flags = CspProviderFlags.UseMachineKeyStore;
rsa = new RSACryptoServiceProvider (csp);
rsa.ImportParameters (rsap);
}
return rsa;
}
catch (Exception e) {
throw new CryptographicException ("Invalid blob.", e);
}
}
// PRIVATEKEYBLOB
// PUBLICKEYBLOB
static public RSA FromCapiKeyBlob (byte[] blob)
{
return FromCapiKeyBlob (blob, 0);
}
static public RSA FromCapiKeyBlob (byte[] blob, int offset)
{
if (blob == null)
throw new ArgumentNullException ("blob");
if (offset >= blob.Length)
throw new ArgumentException ("blob is too small.");
switch (blob [offset]) {
case 0x00:
// this could be a public key inside an header
// like "sn -e" would produce
if (blob [offset + 12] == 0x06) {
return FromCapiPublicKeyBlob (blob, offset + 12);
}
break;
case 0x06:
return FromCapiPublicKeyBlob (blob, offset);
case 0x07:
return FromCapiPrivateKeyBlob (blob, offset);
}
throw new CryptographicException ("Unknown blob format.");
}
}
}
#endif
#endif
}
#endregion
#region Mono.Security.Cryptography\*.cs
namespace Internal {
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// Copyright (c) 2008 - 2015 Jb Evain
// Copyright (c) 2008 - 2011 Novell, Inc.
//
// Licensed under the MIT/X11 license.
//
#if !READ_ONLY
#if !NET_CORE
using System;
using System.IO;
using System.Reflection;
using System.Security.Cryptography;
using System.Runtime.Serialization;
using Mono.Security.Cryptography;
using Mono.Cecil.PE;
namespace Mono.Cecil {
// Most of this code has been adapted
// from Jeroen Frijters' fantastic work
// in IKVM.Reflection.Emit. Thanks!
static class CryptoService {
public static void StrongName (Stream stream, ImageWriter writer, StrongNameKeyPair key_pair)
{
int strong_name_pointer;
var strong_name = CreateStrongName (key_pair, HashStream (stream, writer, out strong_name_pointer));
PatchStrongName (stream, strong_name_pointer, strong_name);
}
static void PatchStrongName (Stream stream, int strong_name_pointer, byte [] strong_name)
{
stream.Seek (strong_name_pointer, SeekOrigin.Begin);
stream.Write (strong_name, 0, strong_name.Length);
}
static byte [] CreateStrongName (StrongNameKeyPair key_pair, byte [] hash)
{
const string hash_algo = "SHA1";
using (var rsa = key_pair.CreateRSA ()) {
var formatter = new RSAPKCS1SignatureFormatter (rsa);
formatter.SetHashAlgorithm (hash_algo);
byte [] signature = formatter.CreateSignature (hash);
Array.Reverse (signature);
return signature;
}
}
static byte [] HashStream (Stream stream, ImageWriter writer, out int strong_name_pointer)
{
const int buffer_size = 8192;
var text = writer.text;
var header_size = (int) writer.GetHeaderSize ();
var text_section_pointer = (int) text.PointerToRawData;
var strong_name_directory = writer.GetStrongNameSignatureDirectory ();
if (strong_name_directory.Size == 0)
throw new InvalidOperationException ();
strong_name_pointer = (int) (text_section_pointer
+ (strong_name_directory.VirtualAddress - text.VirtualAddress));
var strong_name_length = (int) strong_name_directory.Size;
var sha1 = new SHA1Managed ();
var buffer = new byte [buffer_size];
using (var crypto_stream = new CryptoStream (Stream.Null, sha1, CryptoStreamMode.Write)) {
stream.Seek (0, SeekOrigin.Begin);
CopyStreamChunk (stream, crypto_stream, buffer, header_size);
stream.Seek (text_section_pointer, SeekOrigin.Begin);
CopyStreamChunk (stream, crypto_stream, buffer, (int) strong_name_pointer - text_section_pointer);
stream.Seek (strong_name_length, SeekOrigin.Current);
CopyStreamChunk (stream, crypto_stream, buffer, (int) (stream.Length - (strong_name_pointer + strong_name_length)));
}
return sha1.Hash;
}
static void CopyStreamChunk (Stream stream, Stream dest_stream, byte [] buffer, int length)
{
while (length > 0) {
int read = stream.Read (buffer, 0, System.Math.Min (buffer.Length, length));
dest_stream.Write (buffer, 0, read);
length -= read;
}
}
public static byte [] ComputeHash (string file)
{
if (!File.Exists (file))
return Empty<byte>.Array;
const int buffer_size = 8192;
var sha1 = new SHA1Managed ();
using (var stream = new FileStream (file, FileMode.Open, FileAccess.Read, FileShare.Read)) {
var buffer = new byte [buffer_size];
using (var crypto_stream = new CryptoStream (Stream.Null, sha1, CryptoStreamMode.Write))
CopyStreamChunk (stream, crypto_stream, buffer, (int) stream.Length);
}
return sha1.Hash;
}
}
static partial class Mixin {
public static RSA CreateRSA (this StrongNameKeyPair key_pair)
{
byte [] key;
string key_container;
if (!TryGetKeyContainer (key_pair, out key, out key_container))
return CryptoConvert.FromCapiKeyBlob (key);
var parameters = new CspParameters {
Flags = CspProviderFlags.UseMachineKeyStore,
KeyContainerName = key_container,
KeyNumber = 2,
};
return new RSACryptoServiceProvider (parameters);
}
static bool TryGetKeyContainer (ISerializable key_pair, out byte [] key, out string key_container)
{
var info = new SerializationInfo (typeof (StrongNameKeyPair), new FormatterConverter ());
key_pair.GetObjectData (info, new StreamingContext ());
key = (byte []) info.GetValue ("_keyPairArray", typeof (byte []));
key_container = info.GetString ("_keyPairContainer");
return key_container != null;
}
}
}
#endif
#endif
}
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment