5 // Jb Evain (jbevain@gmail.com)
7 // Copyright (c) 2008 - 2011 Jb Evain
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
30 using System.Collections.Generic;
32 using Mono.Cecil.Metadata;
34 namespace Mono.Cecil {
40 public Range (uint index, uint length)
47 sealed class MetadataSystem {
49 internal AssemblyNameReference [] AssemblyReferences;
50 internal ModuleReference [] ModuleReferences;
52 internal TypeDefinition [] Types;
53 internal TypeReference [] TypeReferences;
55 internal FieldDefinition [] Fields;
56 internal MethodDefinition [] Methods;
57 internal MemberReference [] MemberReferences;
59 internal Dictionary<uint, uint []> NestedTypes;
60 internal Dictionary<uint, uint> ReverseNestedTypes;
61 internal Dictionary<uint, MetadataToken []> Interfaces;
62 internal Dictionary<uint, Row<ushort, uint>> ClassLayouts;
63 internal Dictionary<uint, uint> FieldLayouts;
64 internal Dictionary<uint, uint> FieldRVAs;
65 internal Dictionary<MetadataToken, uint> FieldMarshals;
66 internal Dictionary<MetadataToken, Row<ElementType, uint>> Constants;
67 internal Dictionary<uint, MetadataToken []> Overrides;
68 internal Dictionary<MetadataToken, Range> CustomAttributes;
69 internal Dictionary<MetadataToken, Range> SecurityDeclarations;
70 internal Dictionary<uint, Range> Events;
71 internal Dictionary<uint, Range> Properties;
72 internal Dictionary<uint, Row<MethodSemanticsAttributes, MetadataToken>> Semantics;
73 internal Dictionary<uint, Row<PInvokeAttributes, uint, uint>> PInvokes;
74 internal Dictionary<MetadataToken, Range> GenericParameters;
75 internal Dictionary<uint, MetadataToken []> GenericConstraints;
77 static Dictionary<string, Row<ElementType, bool>> primitive_value_types;
79 static void InitializePrimitives ()
81 primitive_value_types = new Dictionary<string, Row<ElementType, bool>> (18) {
82 { "Void", new Row<ElementType, bool> (ElementType.Void, false) },
83 { "Boolean", new Row<ElementType, bool> (ElementType.Boolean, true) },
84 { "Char", new Row<ElementType, bool> (ElementType.Char, true) },
85 { "SByte", new Row<ElementType, bool> (ElementType.I1, true) },
86 { "Byte", new Row<ElementType, bool> (ElementType.U1, true) },
87 { "Int16", new Row<ElementType, bool> (ElementType.I2, true) },
88 { "UInt16", new Row<ElementType, bool> (ElementType.U2, true) },
89 { "Int32", new Row<ElementType, bool> (ElementType.I4, true) },
90 { "UInt32", new Row<ElementType, bool> (ElementType.U4, true) },
91 { "Int64", new Row<ElementType, bool> (ElementType.I8, true) },
92 { "UInt64", new Row<ElementType, bool> (ElementType.U8, true) },
93 { "Single", new Row<ElementType, bool> (ElementType.R4, true) },
94 { "Double", new Row<ElementType, bool> (ElementType.R8, true) },
95 { "String", new Row<ElementType, bool> (ElementType.String, false) },
96 { "TypedReference", new Row<ElementType, bool> (ElementType.TypedByRef, false) },
97 { "IntPtr", new Row<ElementType, bool> (ElementType.I, true) },
98 { "UIntPtr", new Row<ElementType, bool> (ElementType.U, true) },
99 { "Object", new Row<ElementType, bool> (ElementType.Object, false) },
103 public static void TryProcessPrimitiveType (TypeReference type)
105 var scope = type.scope;
109 if (scope.MetadataScopeType != MetadataScopeType.AssemblyNameReference)
112 if (scope.Name != "mscorlib")
115 if (type.Namespace != "System")
118 if (primitive_value_types == null)
119 InitializePrimitives ();
121 Row<ElementType, bool> primitive_data;
122 if (!primitive_value_types.TryGetValue (type.Name, out primitive_data))
125 type.etype = primitive_data.Col1;
126 type.IsValueType = primitive_data.Col2;
131 if (NestedTypes != null) NestedTypes.Clear ();
132 if (ReverseNestedTypes != null) ReverseNestedTypes.Clear ();
133 if (Interfaces != null) Interfaces.Clear ();
134 if (ClassLayouts != null) ClassLayouts.Clear ();
135 if (FieldLayouts != null) FieldLayouts.Clear ();
136 if (FieldRVAs != null) FieldRVAs.Clear ();
137 if (FieldMarshals != null) FieldMarshals.Clear ();
138 if (Constants != null) Constants.Clear ();
139 if (Overrides != null) Overrides.Clear ();
140 if (CustomAttributes != null) CustomAttributes.Clear ();
141 if (SecurityDeclarations != null) SecurityDeclarations.Clear ();
142 if (Events != null) Events.Clear ();
143 if (Properties != null) Properties.Clear ();
144 if (Semantics != null) Semantics.Clear ();
145 if (PInvokes != null) PInvokes.Clear ();
146 if (GenericParameters != null) GenericParameters.Clear ();
147 if (GenericConstraints != null) GenericConstraints.Clear ();
150 public TypeDefinition GetTypeDefinition (uint rid)
152 if (rid < 1 || rid > Types.Length)
155 return Types [rid - 1];
158 public void AddTypeDefinition (TypeDefinition type)
160 Types [type.token.RID - 1] = type;
163 public TypeReference GetTypeReference (uint rid)
165 if (rid < 1 || rid > TypeReferences.Length)
168 return TypeReferences [rid - 1];
171 public void AddTypeReference (TypeReference type)
173 TypeReferences [type.token.RID - 1] = type;
176 public FieldDefinition GetFieldDefinition (uint rid)
178 if (rid < 1 || rid > Fields.Length)
181 return Fields [rid - 1];
184 public void AddFieldDefinition (FieldDefinition field)
186 Fields [field.token.RID - 1] = field;
189 public MethodDefinition GetMethodDefinition (uint rid)
191 if (rid < 1 || rid > Methods.Length)
194 return Methods [rid - 1];
197 public void AddMethodDefinition (MethodDefinition method)
199 Methods [method.token.RID - 1] = method;
202 public MemberReference GetMemberReference (uint rid)
204 if (rid < 1 || rid > MemberReferences.Length)
207 return MemberReferences [rid - 1];
210 public void AddMemberReference (MemberReference member)
212 MemberReferences [member.token.RID - 1] = member;
215 public bool TryGetNestedTypeMapping (TypeDefinition type, out uint [] mapping)
217 return NestedTypes.TryGetValue (type.token.RID, out mapping);
220 public void SetNestedTypeMapping (uint type_rid, uint [] mapping)
222 NestedTypes [type_rid] = mapping;
225 public void RemoveNestedTypeMapping (TypeDefinition type)
227 NestedTypes.Remove (type.token.RID);
230 public bool TryGetReverseNestedTypeMapping (TypeDefinition type, out uint declaring)
232 return ReverseNestedTypes.TryGetValue (type.token.RID, out declaring);
235 public void SetReverseNestedTypeMapping (uint nested, uint declaring)
237 ReverseNestedTypes.Add (nested, declaring);
240 public void RemoveReverseNestedTypeMapping (TypeDefinition type)
242 ReverseNestedTypes.Remove (type.token.RID);
245 public bool TryGetInterfaceMapping (TypeDefinition type, out MetadataToken [] mapping)
247 return Interfaces.TryGetValue (type.token.RID, out mapping);
250 public void SetInterfaceMapping (uint type_rid, MetadataToken [] mapping)
252 Interfaces [type_rid] = mapping;
255 public void RemoveInterfaceMapping (TypeDefinition type)
257 Interfaces.Remove (type.token.RID);
260 public void AddPropertiesRange (uint type_rid, Range range)
262 Properties.Add (type_rid, range);
265 public bool TryGetPropertiesRange (TypeDefinition type, out Range range)
267 return Properties.TryGetValue (type.token.RID, out range);
270 public void RemovePropertiesRange (TypeDefinition type)
272 Properties.Remove (type.token.RID);
275 public void AddEventsRange (uint type_rid, Range range)
277 Events.Add (type_rid, range);
280 public bool TryGetEventsRange (TypeDefinition type, out Range range)
282 return Events.TryGetValue (type.token.RID, out range);
285 public void RemoveEventsRange (TypeDefinition type)
287 Events.Remove (type.token.RID);
290 public bool TryGetGenericParameterRange (IGenericParameterProvider owner, out Range range)
292 return GenericParameters.TryGetValue (owner.MetadataToken, out range);
295 public void RemoveGenericParameterRange (IGenericParameterProvider owner)
297 GenericParameters.Remove (owner.MetadataToken);
300 public bool TryGetCustomAttributeRange (ICustomAttributeProvider owner, out Range range)
302 return CustomAttributes.TryGetValue (owner.MetadataToken, out range);
305 public void RemoveCustomAttributeRange (ICustomAttributeProvider owner)
307 CustomAttributes.Remove (owner.MetadataToken);
310 public bool TryGetSecurityDeclarationRange (ISecurityDeclarationProvider owner, out Range range)
312 return SecurityDeclarations.TryGetValue (owner.MetadataToken, out range);
315 public void RemoveSecurityDeclarationRange (ISecurityDeclarationProvider owner)
317 SecurityDeclarations.Remove (owner.MetadataToken);
320 public bool TryGetGenericConstraintMapping (GenericParameter generic_parameter, out MetadataToken [] mapping)
322 return GenericConstraints.TryGetValue (generic_parameter.token.RID, out mapping);
325 public void SetGenericConstraintMapping (uint gp_rid, MetadataToken [] mapping)
327 GenericConstraints [gp_rid] = mapping;
330 public void RemoveGenericConstraintMapping (GenericParameter generic_parameter)
332 GenericConstraints.Remove (generic_parameter.token.RID);
335 public bool TryGetOverrideMapping (MethodDefinition method, out MetadataToken [] mapping)
337 return Overrides.TryGetValue (method.token.RID, out mapping);
340 public void SetOverrideMapping (uint rid, MetadataToken [] mapping)
342 Overrides [rid] = mapping;
345 public void RemoveOverrideMapping (MethodDefinition method)
347 Overrides.Remove (method.token.RID);
350 public TypeDefinition GetFieldDeclaringType (uint field_rid)
352 return BinaryRangeSearch (Types, field_rid, true);
355 public TypeDefinition GetMethodDeclaringType (uint method_rid)
357 return BinaryRangeSearch (Types, method_rid, false);
360 static TypeDefinition BinaryRangeSearch (TypeDefinition [] types, uint rid, bool field)
363 int max = types.Length - 1;
365 int mid = min + ((max - min) / 2);
366 var type = types [mid];
367 var range = field ? type.fields_range : type.methods_range;
369 if (rid < range.Start)
371 else if (rid >= range.Start + range.Length)