| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650 | //// 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 ILRuntime.Mono.Cecil.Metadata;namespace ILRuntime.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;		}		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 ();		}		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;		}	}}
 |