Replace SIZEOF_REGISTER with sizeof(mgreg_t) for consistency with sizeof(gpointer)
[mono.git] / mcs / class / Mono.Cecil / Mono.Cecil / MetadataSystem.cs
1 //
2 // MetadataSystem.cs
3 //
4 // Author:
5 //   Jb Evain (jbevain@gmail.com)
6 //
7 // Copyright (c) 2008 - 2010 Jb Evain
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.Collections.Generic;
31
32 using Mono.Cecil.Metadata;
33
34 namespace Mono.Cecil {
35
36         struct Range {
37                 public uint Start;
38                 public uint Length;
39
40                 public Range (uint index, uint length)
41                 {
42                         this.Start = index;
43                         this.Length = length;
44                 }
45         }
46
47         sealed class MetadataSystem {
48
49                 internal TypeDefinition [] Types;
50                 internal TypeReference [] TypeReferences;
51
52                 internal FieldDefinition [] Fields;
53                 internal MethodDefinition [] Methods;
54                 internal MemberReference [] MemberReferences;
55
56                 internal Dictionary<uint, uint []> NestedTypes;
57                 internal Dictionary<uint, uint> ReverseNestedTypes;
58                 internal Dictionary<uint, MetadataToken []> Interfaces;
59                 internal Dictionary<uint, Row<ushort, uint>> ClassLayouts;
60                 internal Dictionary<uint, uint> FieldLayouts;
61                 internal Dictionary<uint, uint> FieldRVAs;
62                 internal Dictionary<MetadataToken, uint> FieldMarshals;
63                 internal Dictionary<MetadataToken, Row<ElementType, uint>> Constants;
64                 internal Dictionary<uint, MetadataToken []> Overrides;
65                 internal Dictionary<MetadataToken, Range> CustomAttributes;
66                 internal Dictionary<MetadataToken, Range> SecurityDeclarations;
67                 internal Dictionary<uint, Range> Events;
68                 internal Dictionary<uint, Range> Properties;
69                 internal Dictionary<uint, Row<MethodSemanticsAttributes, MetadataToken>> Semantics;
70                 internal Dictionary<uint, Row<PInvokeAttributes, uint, uint>> PInvokes;
71                 internal Dictionary<MetadataToken, Range> GenericParameters;
72                 internal Dictionary<uint, MetadataToken []> GenericConstraints;
73
74                 static Dictionary<string, Row<ElementType, bool>> primitive_value_types;
75
76                 static void InitializePrimitives ()
77                 {
78                         primitive_value_types = new Dictionary<string, Row<ElementType, bool>> (18) {
79                                 { "Void", new Row<ElementType, bool> (ElementType.Void, false) },
80                                 { "Boolean", new Row<ElementType, bool> (ElementType.Boolean, true) },
81                                 { "Char", new Row<ElementType, bool> (ElementType.Char, true) },
82                                 { "SByte", new Row<ElementType, bool> (ElementType.I1, true) },
83                                 { "Byte", new Row<ElementType, bool> (ElementType.U1, true) },
84                                 { "Int16", new Row<ElementType, bool> (ElementType.I2, true) },
85                                 { "UInt16", new Row<ElementType, bool> (ElementType.U2, true) },
86                                 { "Int32", new Row<ElementType, bool> (ElementType.I4, true) },
87                                 { "UInt32", new Row<ElementType, bool> (ElementType.U4, true) },
88                                 { "Int64", new Row<ElementType, bool> (ElementType.I8, true) },
89                                 { "UInt64", new Row<ElementType, bool> (ElementType.U8, true) },
90                                 { "Single", new Row<ElementType, bool> (ElementType.R4, true) },
91                                 { "Double", new Row<ElementType, bool> (ElementType.R8, true) },
92                                 { "String", new Row<ElementType, bool> (ElementType.String, false) },
93                                 { "TypedReference", new Row<ElementType, bool> (ElementType.TypedByRef, false) },
94                                 { "IntPtr", new Row<ElementType, bool> (ElementType.I, true) },
95                                 { "UIntPtr", new Row<ElementType, bool> (ElementType.U, true) },
96                                 { "Object", new Row<ElementType, bool> (ElementType.Object, false) },
97                         };
98                 }
99
100                 public static void TryProcessPrimitiveType (TypeReference type)
101                 {
102                         var scope = type.scope;
103                         if (scope.MetadataScopeType != MetadataScopeType.AssemblyNameReference)
104                                 return;
105
106                         if (scope.Name != "mscorlib")
107                                 return;
108
109                         if (type.Namespace != "System")
110                                 return;
111
112                         if (primitive_value_types == null)
113                                 InitializePrimitives ();
114
115                         Row<ElementType, bool> primitive_data;
116                         if (!primitive_value_types.TryGetValue (type.Name, out primitive_data))
117                                 return;
118
119                         type.etype = primitive_data.Col1;
120                         type.IsValueType = primitive_data.Col2;
121                 }
122
123                 public void Clear ()
124                 {
125                         if (NestedTypes != null) NestedTypes.Clear ();
126                         if (ReverseNestedTypes != null) ReverseNestedTypes.Clear ();
127                         if (Interfaces != null) Interfaces.Clear ();
128                         if (ClassLayouts != null) ClassLayouts.Clear ();
129                         if (FieldLayouts != null) FieldLayouts.Clear ();
130                         if (FieldRVAs != null) FieldRVAs.Clear ();
131                         if (FieldMarshals != null) FieldMarshals.Clear ();
132                         if (Constants != null) Constants.Clear ();
133                         if (Overrides != null) Overrides.Clear ();
134                         if (CustomAttributes != null) CustomAttributes.Clear ();
135                         if (SecurityDeclarations != null) SecurityDeclarations.Clear ();
136                         if (Events != null) Events.Clear ();
137                         if (Properties != null) Properties.Clear ();
138                         if (Semantics != null) Semantics.Clear ();
139                         if (PInvokes != null) PInvokes.Clear ();
140                         if (GenericParameters != null) GenericParameters.Clear ();
141                         if (GenericConstraints != null) GenericConstraints.Clear ();
142                 }
143
144                 public TypeDefinition GetTypeDefinition (uint rid)
145                 {
146                         if (rid < 1 || rid > Types.Length)
147                                 return null;
148
149                         return Types [rid - 1];
150                 }
151
152                 public void AddTypeDefinition (TypeDefinition type)
153                 {
154                         Types [type.token.RID - 1] = type;
155                 }
156
157                 public TypeReference GetTypeReference (uint rid)
158                 {
159                         if (rid < 1 || rid > TypeReferences.Length)
160                                 return null;
161
162                         return TypeReferences [rid - 1];
163                 }
164
165                 public void AddTypeReference (TypeReference type)
166                 {
167                         TypeReferences [type.token.RID - 1] = type;
168                 }
169
170                 public FieldDefinition GetFieldDefinition (uint rid)
171                 {
172                         if (rid < 1 || rid > Fields.Length)
173                                 return null;
174
175                         return Fields [rid - 1];
176                 }
177
178                 public void AddFieldDefinition (FieldDefinition field)
179                 {
180                         Fields [field.token.RID - 1] = field;
181                 }
182
183                 public MethodDefinition GetMethodDefinition (uint rid)
184                 {
185                         if (rid < 1 || rid > Methods.Length)
186                                 return null;
187
188                         return Methods [rid - 1];
189                 }
190
191                 public void AddMethodDefinition (MethodDefinition method)
192                 {
193                         Methods [method.token.RID - 1] = method;
194                 }
195
196                 public MemberReference GetMemberReference (uint rid)
197                 {
198                         if (rid < 1 || rid > MemberReferences.Length)
199                                 return null;
200
201                         return MemberReferences [rid - 1];
202                 }
203
204                 public void AddMemberReference (MemberReference member)
205                 {
206                         MemberReferences [member.token.RID - 1] = member;
207                 }
208
209                 public bool TryGetNestedTypeMapping (TypeDefinition type, out uint [] mapping)
210                 {
211                         return NestedTypes.TryGetValue (type.token.RID, out mapping);
212                 }
213
214                 public void SetNestedTypeMapping (uint type_rid, uint [] mapping)
215                 {
216                         NestedTypes [type_rid] = mapping;
217                 }
218
219                 public void RemoveNestedTypeMapping (TypeDefinition type)
220                 {
221                         NestedTypes.Remove (type.token.RID);
222                 }
223
224                 public bool TryGetReverseNestedTypeMapping (TypeDefinition type, out uint declaring)
225                 {
226                         return ReverseNestedTypes.TryGetValue (type.token.RID, out declaring);
227                 }
228
229                 public void SetReverseNestedTypeMapping (uint nested, uint declaring)
230                 {
231                         ReverseNestedTypes.Add (nested, declaring);
232                 }
233
234                 public void RemoveReverseNestedTypeMapping (TypeDefinition type)
235                 {
236                         ReverseNestedTypes.Remove (type.token.RID);
237                 }
238
239                 public bool TryGetInterfaceMapping (TypeDefinition type, out MetadataToken [] mapping)
240                 {
241                         return Interfaces.TryGetValue (type.token.RID, out mapping);
242                 }
243
244                 public void SetInterfaceMapping (uint type_rid, MetadataToken [] mapping)
245                 {
246                         Interfaces [type_rid] = mapping;
247                 }
248
249                 public void RemoveInterfaceMapping (TypeDefinition type)
250                 {
251                         Interfaces.Remove (type.token.RID);
252                 }
253
254                 public void AddPropertiesRange (uint type_rid, Range range)
255                 {
256                         Properties.Add (type_rid, range);
257                 }
258
259                 public bool TryGetPropertiesRange (TypeDefinition type, out Range range)
260                 {
261                         return Properties.TryGetValue (type.token.RID, out range);
262                 }
263
264                 public void RemovePropertiesRange (TypeDefinition type)
265                 {
266                         Properties.Remove (type.token.RID);
267                 }
268
269                 public void AddEventsRange (uint type_rid, Range range)
270                 {
271                         Events.Add (type_rid, range);
272                 }
273
274                 public bool TryGetEventsRange (TypeDefinition type, out Range range)
275                 {
276                         return Events.TryGetValue (type.token.RID, out range);
277                 }
278
279                 public void RemoveEventsRange (TypeDefinition type)
280                 {
281                         Events.Remove (type.token.RID);
282                 }
283
284                 public bool TryGetGenericParameterRange (IGenericParameterProvider owner, out Range range)
285                 {
286                         return GenericParameters.TryGetValue (owner.MetadataToken, out range);
287                 }
288
289                 public void RemoveGenericParameterRange (IGenericParameterProvider owner)
290                 {
291                         GenericParameters.Remove (owner.MetadataToken);
292                 }
293
294                 public bool TryGetCustomAttributeRange (ICustomAttributeProvider owner, out Range range)
295                 {
296                         return CustomAttributes.TryGetValue (owner.MetadataToken, out range);
297                 }
298
299                 public void RemoveCustomAttributeRange (ICustomAttributeProvider owner)
300                 {
301                         CustomAttributes.Remove (owner.MetadataToken);
302                 }
303
304                 public bool TryGetSecurityDeclarationRange (ISecurityDeclarationProvider owner, out Range range)
305                 {
306                         return SecurityDeclarations.TryGetValue (owner.MetadataToken, out range);
307                 }
308
309                 public void RemoveSecurityDeclarationRange (ISecurityDeclarationProvider owner)
310                 {
311                         SecurityDeclarations.Remove (owner.MetadataToken);
312                 }
313
314                 public bool TryGetGenericConstraintMapping (GenericParameter generic_parameter, out MetadataToken [] mapping)
315                 {
316                         return GenericConstraints.TryGetValue (generic_parameter.token.RID, out mapping);
317                 }
318
319                 public void SetGenericConstraintMapping (uint gp_rid, MetadataToken [] mapping)
320                 {
321                         GenericConstraints [gp_rid] = mapping;
322                 }
323
324                 public void RemoveGenericConstraintMapping (GenericParameter generic_parameter)
325                 {
326                         GenericConstraints.Remove (generic_parameter.token.RID);
327                 }
328
329                 public bool TryGetOverrideMapping (MethodDefinition method, out MetadataToken [] mapping)
330                 {
331                         return Overrides.TryGetValue (method.token.RID, out mapping);
332                 }
333
334                 public void SetOverrideMapping (uint rid, MetadataToken [] mapping)
335                 {
336                         Overrides [rid] = mapping;
337                 }
338
339                 public void RemoveOverrideMapping (MethodDefinition method)
340                 {
341                         Overrides.Remove (method.token.RID);
342                 }
343
344                 public TypeDefinition GetFieldDeclaringType (uint field_rid)
345                 {
346                         return BinaryRangeSearch (Types, field_rid, true);
347                 }
348
349                 public TypeDefinition GetMethodDeclaringType (uint method_rid)
350                 {
351                         return BinaryRangeSearch (Types, method_rid, false);
352                 }
353
354                 static TypeDefinition BinaryRangeSearch (TypeDefinition [] types, uint rid, bool field)
355                 {
356                         int min = 0;
357                         int max = types.Length - 1;
358                         while (min <= max) {
359                                 int mid = min + ((max - min) / 2);
360                                 var type = types [mid];
361                                 var range = field ? type.fields_range : type.methods_range;
362
363                                 if (rid < range.Start)
364                                         max = mid - 1;
365                                 else if (rid >= range.Start + range.Length)
366                                         min = mid + 1;
367                                 else
368                                         return type;
369                         }
370
371                         throw new ArgumentException ();
372                 }
373         }
374 }