1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.Runtime.CompilerServices;
6 
7 namespace System.Reflection.Metadata.Ecma335
8 {
9     internal static class HasCustomDebugInformationTag
10     {
11         internal const int NumberOfBits = 5;
12         internal const int LargeRowSize = 0x00000001 << (16 - NumberOfBits);
13 
14         internal const uint MethodDef = 0x00000000;
15         internal const uint Field = 0x00000001;
16         internal const uint TypeRef = 0x00000002;
17         internal const uint TypeDef = 0x00000003;
18         internal const uint Param = 0x00000004;
19         internal const uint InterfaceImpl = 0x00000005;
20         internal const uint MemberRef = 0x00000006;
21         internal const uint Module = 0x00000007;
22         internal const uint DeclSecurity = 0x00000008;
23         internal const uint Property = 0x00000009;
24         internal const uint Event = 0x0000000A;
25         internal const uint StandAloneSig = 0x0000000B;
26         internal const uint ModuleRef = 0x0000000C;
27         internal const uint TypeSpec = 0x0000000D;
28         internal const uint Assembly = 0x0000000E;
29         internal const uint AssemblyRef = 0x0000000F;
30         internal const uint File = 0x00000010;
31         internal const uint ExportedType = 0x00000011;
32         internal const uint ManifestResource = 0x00000012;
33         internal const uint GenericParam = 0x00000013;
34         internal const uint GenericParamConstraint = 0x00000014;
35         internal const uint MethodSpec = 0x00000015;
36 
37         internal const uint Document = 0x00000016;
38         internal const uint LocalScope = 0x00000017;
39         internal const uint LocalVariable = 0x00000018;
40         internal const uint LocalConstant = 0x00000019;
41         internal const uint Import = 0x0000001a;
42 
43         internal const uint TagMask = 0x0000001F;
44 
45         // Arbitrary value not equal to any of the token types in the array. This includes 0 which is TokenTypeIds.Module.
46         internal const uint InvalidTokenType = uint.MaxValue;
47 
48         internal static uint[] TagToTokenTypeArray =
49         {
50             TokenTypeIds.MethodDef,
51             TokenTypeIds.FieldDef,
52             TokenTypeIds.TypeRef,
53             TokenTypeIds.TypeDef,
54             TokenTypeIds.ParamDef,
55             TokenTypeIds.InterfaceImpl,
56             TokenTypeIds.MemberRef,
57             TokenTypeIds.Module,
58             TokenTypeIds.DeclSecurity,
59             TokenTypeIds.Property,
60             TokenTypeIds.Event,
61             TokenTypeIds.Signature,
62             TokenTypeIds.ModuleRef,
63             TokenTypeIds.TypeSpec,
64             TokenTypeIds.Assembly,
65             TokenTypeIds.AssemblyRef,
66             TokenTypeIds.File,
67             TokenTypeIds.ExportedType,
68             TokenTypeIds.ManifestResource,
69             TokenTypeIds.GenericParam,
70             TokenTypeIds.GenericParamConstraint,
71             TokenTypeIds.MethodSpec,
72 
73             TokenTypeIds.Document,
74             TokenTypeIds.LocalScope,
75             TokenTypeIds.LocalVariable,
76             TokenTypeIds.LocalConstant,
77             TokenTypeIds.ImportScope,
78 
79             InvalidTokenType,
80             InvalidTokenType,
81             InvalidTokenType,
82             InvalidTokenType,
83             InvalidTokenType
84         };
85 
86         internal const TableMask TablesReferenced =
87           TableMask.MethodDef
88           | TableMask.Field
89           | TableMask.TypeRef
90           | TableMask.TypeDef
91           | TableMask.Param
92           | TableMask.InterfaceImpl
93           | TableMask.MemberRef
94           | TableMask.Module
95           | TableMask.DeclSecurity
96           | TableMask.Property
97           | TableMask.Event
98           | TableMask.StandAloneSig
99           | TableMask.ModuleRef
100           | TableMask.TypeSpec
101           | TableMask.Assembly
102           | TableMask.AssemblyRef
103           | TableMask.File
104           | TableMask.ExportedType
105           | TableMask.ManifestResource
106           | TableMask.GenericParam
107           | TableMask.GenericParamConstraint
108           | TableMask.MethodSpec
109           | TableMask.Document
110           | TableMask.LocalScope
111           | TableMask.LocalVariable
112           | TableMask.LocalConstant
113           | TableMask.ImportScope;
114 
115         [MethodImpl(MethodImplOptions.AggressiveInlining)]
ConvertToHandle(uint taggedReference)116         internal static EntityHandle ConvertToHandle(uint taggedReference)
117         {
118             uint tokenType = TagToTokenTypeArray[taggedReference & TagMask];
119             uint rowId = (taggedReference >> NumberOfBits);
120 
121             if (tokenType == InvalidTokenType || ((rowId & ~TokenTypeIds.RIDMask) != 0))
122             {
123                 Throw.InvalidCodedIndex();
124             }
125 
126             return new EntityHandle(tokenType | rowId);
127         }
128 
ConvertToTag(EntityHandle handle)129         internal static uint ConvertToTag(EntityHandle handle)
130         {
131             uint tokenType = handle.Type;
132             uint rowId = (uint)handle.RowId;
133             switch (tokenType >> TokenTypeIds.RowIdBitCount)
134             {
135                 case TokenTypeIds.MethodDef >> TokenTypeIds.RowIdBitCount:
136                     return rowId << NumberOfBits | MethodDef;
137                 case TokenTypeIds.FieldDef >> TokenTypeIds.RowIdBitCount:
138                     return rowId << NumberOfBits | Field;
139                 case TokenTypeIds.TypeRef >> TokenTypeIds.RowIdBitCount:
140                     return rowId << NumberOfBits | TypeRef;
141                 case TokenTypeIds.TypeDef >> TokenTypeIds.RowIdBitCount:
142                     return rowId << NumberOfBits | TypeDef;
143                 case TokenTypeIds.ParamDef >> TokenTypeIds.RowIdBitCount:
144                     return rowId << NumberOfBits | Param;
145                 case TokenTypeIds.InterfaceImpl >> TokenTypeIds.RowIdBitCount:
146                     return rowId << NumberOfBits | InterfaceImpl;
147                 case TokenTypeIds.MemberRef >> TokenTypeIds.RowIdBitCount:
148                     return rowId << NumberOfBits | MemberRef;
149                 case TokenTypeIds.Module >> TokenTypeIds.RowIdBitCount:
150                     return rowId << NumberOfBits | Module;
151                 case TokenTypeIds.DeclSecurity >> TokenTypeIds.RowIdBitCount:
152                     return rowId << NumberOfBits | DeclSecurity;
153                 case TokenTypeIds.Property >> TokenTypeIds.RowIdBitCount:
154                     return rowId << NumberOfBits | Property;
155                 case TokenTypeIds.Event >> TokenTypeIds.RowIdBitCount:
156                     return rowId << NumberOfBits | Event;
157                 case TokenTypeIds.Signature >> TokenTypeIds.RowIdBitCount:
158                     return rowId << NumberOfBits | StandAloneSig;
159                 case TokenTypeIds.ModuleRef >> TokenTypeIds.RowIdBitCount:
160                     return rowId << NumberOfBits | ModuleRef;
161                 case TokenTypeIds.TypeSpec >> TokenTypeIds.RowIdBitCount:
162                     return rowId << NumberOfBits | TypeSpec;
163                 case TokenTypeIds.Assembly >> TokenTypeIds.RowIdBitCount:
164                     return rowId << NumberOfBits | Assembly;
165                 case TokenTypeIds.AssemblyRef >> TokenTypeIds.RowIdBitCount:
166                     return rowId << NumberOfBits | AssemblyRef;
167                 case TokenTypeIds.File >> TokenTypeIds.RowIdBitCount:
168                     return rowId << NumberOfBits | File;
169                 case TokenTypeIds.ExportedType >> TokenTypeIds.RowIdBitCount:
170                     return rowId << NumberOfBits | ExportedType;
171                 case TokenTypeIds.ManifestResource >> TokenTypeIds.RowIdBitCount:
172                     return rowId << NumberOfBits | ManifestResource;
173                 case TokenTypeIds.GenericParam >> TokenTypeIds.RowIdBitCount:
174                     return rowId << NumberOfBits | GenericParam;
175                 case TokenTypeIds.GenericParamConstraint >> TokenTypeIds.RowIdBitCount:
176                     return rowId << NumberOfBits | GenericParamConstraint;
177                 case TokenTypeIds.MethodSpec >> TokenTypeIds.RowIdBitCount:
178                     return rowId << NumberOfBits | MethodSpec;
179 
180                 case TokenTypeIds.Document >> TokenTypeIds.RowIdBitCount:
181                     return rowId << NumberOfBits | Document;
182                 case TokenTypeIds.LocalScope >> TokenTypeIds.RowIdBitCount:
183                     return rowId << NumberOfBits | LocalScope;
184                 case TokenTypeIds.LocalVariable >> TokenTypeIds.RowIdBitCount:
185                     return rowId << NumberOfBits | LocalVariable;
186                 case TokenTypeIds.LocalConstant >> TokenTypeIds.RowIdBitCount:
187                     return rowId << NumberOfBits | LocalConstant;
188                 case TokenTypeIds.ImportScope >> TokenTypeIds.RowIdBitCount:
189                     return rowId << NumberOfBits | Import;
190             }
191 
192             return 0;
193         }
194     }
195 }
196