Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/cecil.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJb Evain <jbevain@gmail.com>2012-12-03 22:23:45 +0400
committerJb Evain <jbevain@gmail.com>2012-12-03 22:23:45 +0400
commitd9976f58f40fe9973a015198e1cc7d3773c4b640 (patch)
tree7ea9e57e120c42e74e4e07e18a7cfd52141c93ef
parent9bfe76be006fbf8cd2dc4df20b00764e8faecfc7 (diff)
Properly read unsorted GenericParam, DeclSecl and CustomAttr tables
-rw-r--r--Mono.Cecil/AssemblyReader.cs117
-rw-r--r--Mono.Cecil/MetadataSystem.cs18
-rw-r--r--Mono.Cecil/TypeParser.cs8
-rw-r--r--Mono/Empty.cs14
4 files changed, 106 insertions, 51 deletions
diff --git a/Mono.Cecil/AssemblyReader.cs b/Mono.Cecil/AssemblyReader.cs
index 89d300f..eb7bdb8 100644
--- a/Mono.Cecil/AssemblyReader.cs
+++ b/Mono.Cecil/AssemblyReader.cs
@@ -1787,25 +1787,35 @@ namespace Mono.Cecil {
{
InitializeGenericParameters ();
- Range range;
- if (!metadata.TryGetGenericParameterRange (provider, out range))
+ Range [] ranges;
+ if (!metadata.TryGetGenericParameterRanges (provider, out ranges))
return false;
- return range.Length > 0;
+ return RangesSize (ranges) > 0;
}
public Collection<GenericParameter> ReadGenericParameters (IGenericParameterProvider provider)
{
InitializeGenericParameters ();
- Range range;
- if (!metadata.TryGetGenericParameterRange (provider, out range)
- || !MoveTo (Table.GenericParam, range.Start))
+ Range [] ranges;
+ if (!metadata.TryGetGenericParameterRanges (provider, out ranges))
return new GenericParameterCollection (provider);
metadata.RemoveGenericParameterRange (provider);
- var generic_parameters = new GenericParameterCollection (provider, (int) range.Length);
+ 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
@@ -1819,8 +1829,6 @@ namespace Mono.Cecil {
generic_parameters.Add (parameter);
}
-
- return generic_parameters;
}
void InitializeGenericParameters ()
@@ -1837,10 +1845,10 @@ namespace Mono.Cecil {
});
}
- Dictionary<MetadataToken, Range> InitializeRanges (Table table, Func<MetadataToken> get_next)
+ Dictionary<MetadataToken, Range []> InitializeRanges (Table table, Func<MetadataToken> get_next)
{
int length = MoveTo (table);
- var ranges = new Dictionary<MetadataToken, Range> (length);
+ var ranges = new Dictionary<MetadataToken, Range []> (length);
if (length == 0)
return ranges;
@@ -1855,20 +1863,34 @@ namespace Mono.Cecil {
owner = next;
range.Length++;
} else if (next != owner) {
- if (owner.RID != 0)
- ranges.Add (owner, range);
+ AddRange (ranges, owner, range);
range = new Range (i, 1);
owner = next;
} else
range.Length++;
}
- if (owner != MetadataToken.Zero && !ranges.ContainsKey (owner))
- ranges.Add (owner, range);
+ 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;
+ }
+
+ slots = slots.Resize (slots.Length + 1);
+ slots [slots.Length - 1] = range;
+ ranges [owner] = slots;
+ }
+
public bool HasGenericConstraints (GenericParameter generic_parameter)
{
InitializeGenericConstraints ();
@@ -2332,23 +2354,35 @@ namespace Mono.Cecil {
{
InitializeCustomAttributes ();
- Range range;
- if (!metadata.TryGetCustomAttributeRange (owner, out range))
+ Range [] ranges;
+ if (!metadata.TryGetCustomAttributeRanges (owner, out ranges))
return false;
- return range.Length > 0;
+ return RangesSize (ranges) > 0;
}
public Collection<CustomAttribute> ReadCustomAttributes (ICustomAttributeProvider owner)
{
InitializeCustomAttributes ();
- Range range;
- if (!metadata.TryGetCustomAttributeRange (owner, out range)
- || !MoveTo (Table.CustomAttribute, range.Start))
+ Range [] ranges;
+ if (!metadata.TryGetCustomAttributeRanges (owner, out ranges))
return new Collection<CustomAttribute> ();
- var custom_attributes = new Collection<CustomAttribute> ((int) range.Length);
+ var custom_attributes = new Collection<CustomAttribute> (RangesSize (ranges));
+
+ for (int i = 0; i < ranges.Length; i++)
+ ReadCustomAttributeRange (ranges [i], custom_attributes);
+
+ metadata.RemoveCustomAttributeRange (owner);
+
+ return custom_attributes;
+ }
+
+ void ReadCustomAttributeRange (Range range, Collection<CustomAttribute> custom_attributes)
+ {
+ if (!MoveTo (Table.CustomAttribute, range.Start))
+ return;
for (int i = 0; i < range.Length; i++) {
ReadMetadataToken (CodedIndex.HasCustomAttribute);
@@ -2360,10 +2394,15 @@ namespace Mono.Cecil {
custom_attributes.Add (new CustomAttribute (signature, constructor));
}
+ }
- metadata.RemoveCustomAttributeRange (owner);
+ static int RangesSize (Range [] ranges)
+ {
+ uint size = 0;
+ for (int i = 0; i < ranges.Length; i++)
+ size += ranges [i].Length;
- return custom_attributes;
+ return (int) size;
}
public byte [] ReadCustomAttributeBlob (uint signature)
@@ -2455,23 +2494,35 @@ namespace Mono.Cecil {
{
InitializeSecurityDeclarations ();
- Range range;
- if (!metadata.TryGetSecurityDeclarationRange (owner, out range))
+ Range [] ranges;
+ if (!metadata.TryGetSecurityDeclarationRanges (owner, out ranges))
return false;
- return range.Length > 0;
+ return RangesSize (ranges) > 0;
}
public Collection<SecurityDeclaration> ReadSecurityDeclarations (ISecurityDeclarationProvider owner)
{
InitializeSecurityDeclarations ();
- Range range;
- if (!metadata.TryGetSecurityDeclarationRange (owner, out range)
- || !MoveTo (Table.DeclSecurity, range.Start))
+ Range [] ranges;
+ if (!metadata.TryGetSecurityDeclarationRanges (owner, out ranges))
return new Collection<SecurityDeclaration> ();
- var security_declarations = new Collection<SecurityDeclaration> ((int) range.Length);
+ 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 ();
@@ -2480,10 +2531,6 @@ namespace Mono.Cecil {
security_declarations.Add (new SecurityDeclaration (action, signature, module));
}
-
- metadata.RemoveSecurityDeclarationRange (owner);
-
- return security_declarations;
}
public byte [] ReadSecurityDeclarationBlob (uint signature)
diff --git a/Mono.Cecil/MetadataSystem.cs b/Mono.Cecil/MetadataSystem.cs
index 72b04f2..3ae2015 100644
--- a/Mono.Cecil/MetadataSystem.cs
+++ b/Mono.Cecil/MetadataSystem.cs
@@ -65,13 +65,13 @@ namespace Mono.Cecil {
internal Dictionary<MetadataToken, uint> FieldMarshals;
internal Dictionary<MetadataToken, Row<ElementType, uint>> Constants;
internal Dictionary<uint, MetadataToken []> Overrides;
- internal Dictionary<MetadataToken, Range> CustomAttributes;
- internal Dictionary<MetadataToken, Range> SecurityDeclarations;
+ 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<MetadataToken, Range []> GenericParameters;
internal Dictionary<uint, MetadataToken []> GenericConstraints;
static Dictionary<string, Row<ElementType, bool>> primitive_value_types;
@@ -302,9 +302,9 @@ namespace Mono.Cecil {
Events.Remove (type.token.RID);
}
- public bool TryGetGenericParameterRange (IGenericParameterProvider owner, out Range range)
+ public bool TryGetGenericParameterRanges (IGenericParameterProvider owner, out Range [] ranges)
{
- return GenericParameters.TryGetValue (owner.MetadataToken, out range);
+ return GenericParameters.TryGetValue (owner.MetadataToken, out ranges);
}
public void RemoveGenericParameterRange (IGenericParameterProvider owner)
@@ -312,9 +312,9 @@ namespace Mono.Cecil {
GenericParameters.Remove (owner.MetadataToken);
}
- public bool TryGetCustomAttributeRange (ICustomAttributeProvider owner, out Range range)
+ public bool TryGetCustomAttributeRanges (ICustomAttributeProvider owner, out Range [] ranges)
{
- return CustomAttributes.TryGetValue (owner.MetadataToken, out range);
+ return CustomAttributes.TryGetValue (owner.MetadataToken, out ranges);
}
public void RemoveCustomAttributeRange (ICustomAttributeProvider owner)
@@ -322,9 +322,9 @@ namespace Mono.Cecil {
CustomAttributes.Remove (owner.MetadataToken);
}
- public bool TryGetSecurityDeclarationRange (ISecurityDeclarationProvider owner, out Range range)
+ public bool TryGetSecurityDeclarationRanges (ISecurityDeclarationProvider owner, out Range [] ranges)
{
- return SecurityDeclarations.TryGetValue (owner.MetadataToken, out range);
+ return SecurityDeclarations.TryGetValue (owner.MetadataToken, out ranges);
}
public void RemoveSecurityDeclarationRange (ISecurityDeclarationProvider owner)
diff --git a/Mono.Cecil/TypeParser.cs b/Mono.Cecil/TypeParser.cs
index 3e633ea..90e04a6 100644
--- a/Mono.Cecil/TypeParser.cs
+++ b/Mono.Cecil/TypeParser.cs
@@ -173,13 +173,7 @@ namespace Mono.Cecil {
return;
}
-#if !CF
- Array.Resize (ref array, array.Length + 1);
-#else
- var copy = new T [array.Length + 1];
- Array.Copy (array, copy, array.Length);
- array = copy;
-#endif
+ array = array.Resize (array.Length + 1);
array [array.Length - 1] = item;
}
diff --git a/Mono/Empty.cs b/Mono/Empty.cs
index d043a35..820bc34 100644
--- a/Mono/Empty.cs
+++ b/Mono/Empty.cs
@@ -26,6 +26,7 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+using System;
using Mono.Collections.Generic;
namespace Mono {
@@ -49,5 +50,18 @@ namespace Mono.Cecil {
{
return self == null || self.size == 0;
}
+
+ public static T [] Resize<T> (this T [] self, int length)
+ {
+#if !CF
+ Array.Resize (ref self, length);
+#else
+ var copy = new T [length];
+ Array.Copy (self, copy, self.Length);
+ array = copy;
+#endif
+
+ return self;
+ }
}
}