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:
-rw-r--r--Mono.Cecil.Cil/MethodBody.cs13
-rw-r--r--Test/Mono.Cecil.Tests/ILProcessorTests.cs85
2 files changed, 57 insertions, 41 deletions
diff --git a/Mono.Cecil.Cil/MethodBody.cs b/Mono.Cecil.Cil/MethodBody.cs
index 1aecb57..c9236db 100644
--- a/Mono.Cecil.Cil/MethodBody.cs
+++ b/Mono.Cecil.Cil/MethodBody.cs
@@ -384,11 +384,16 @@ namespace Mono.Cecil.Cil {
// resolve by walking the instructions from start and don't cache the result.
int size = 0;
for (int i = 0; i < items.Length; i++) {
+ // The array can be larger than the actual size, in which case its padded with nulls at the end
+ // so when we reach null, treat it as an end of the IL.
+ if (items [i] == null)
+ return new InstructionOffset (i == 0 ? items [0] : items [i - 1]);
+
if (size == offset)
return new InstructionOffset (items [i]);
if (size > offset)
- return new InstructionOffset (items [i - 1]);
+ return new InstructionOffset (i == 0 ? items [0] : items [i - 1]);
size += items [i].GetSize ();
}
@@ -407,15 +412,15 @@ namespace Mono.Cecil.Cil {
// Allow for trailing null values in the case of
// instructions.Size < instructions.Capacity
if (item == null)
- return new InstructionOffset (items [i - 1]);
+ return new InstructionOffset (i == 0 ? items [0] : items [i - 1]);
cache.Instruction = item;
if (cache.Offset == offset)
return new InstructionOffset (cache.Instruction);
- if (cache.Offset > offset)
- return new InstructionOffset (items [i - 1]);
+ if (cache.Offset > offset)
+ return new InstructionOffset (i == 0 ? items [0] : items [i - 1]);
size += item.GetSize ();
}
diff --git a/Test/Mono.Cecil.Tests/ILProcessorTests.cs b/Test/Mono.Cecil.Tests/ILProcessorTests.cs
index c585403..c1dc13c 100644
--- a/Test/Mono.Cecil.Tests/ILProcessorTests.cs
+++ b/Test/Mono.Cecil.Tests/ILProcessorTests.cs
@@ -152,16 +152,18 @@ namespace Mono.Cecil.Tests {
AssertOpCodeSequence (new OpCode[] { }, method);
}
- [TestCase (RoundtripType.None, false, false)]
- [TestCase (RoundtripType.Pdb, false, false)]
- [TestCase (RoundtripType.Pdb, true, false)]
- [TestCase (RoundtripType.Pdb, true, true)]
- [TestCase (RoundtripType.PortablePdb, false, false)]
- [TestCase (RoundtripType.PortablePdb, true, false)]
- [TestCase (RoundtripType.PortablePdb, true, true)]
- public void InsertAfterWithSymbolRoundtrip (RoundtripType roundtripType, bool forceUnresolved, bool reverseScopes)
+ [TestCase (RoundtripType.None, false, false, false)]
+ [TestCase (RoundtripType.Pdb, false, false, false)]
+ [TestCase (RoundtripType.Pdb, true, false, false)]
+ [TestCase (RoundtripType.Pdb, true, false, true)]
+ [TestCase (RoundtripType.Pdb, true, true, false)]
+ [TestCase (RoundtripType.PortablePdb, false, false, false)]
+ [TestCase (RoundtripType.PortablePdb, true, false, false)]
+ [TestCase (RoundtripType.PortablePdb, true, false, true)]
+ [TestCase (RoundtripType.PortablePdb, true, true, false)]
+ public void InsertAfterWithSymbolRoundtrip (RoundtripType roundtripType, bool forceUnresolved, bool reverseScopes, bool padIL)
{
- var methodBody = CreateTestMethodWithLocalScopes ();
+ var methodBody = CreateTestMethodWithLocalScopes (padIL);
methodBody = RoundtripMethodBody (methodBody, roundtripType, forceUnresolved, reverseScopes);
var il = methodBody.GetILProcessor ();
@@ -176,16 +178,18 @@ namespace Mono.Cecil.Tests {
methodBody.Method.Module.Dispose ();
}
- [TestCase (RoundtripType.None, false, false)]
- [TestCase (RoundtripType.Pdb, false, false)]
- [TestCase (RoundtripType.Pdb, true, false)]
- [TestCase (RoundtripType.Pdb, true, true)]
- [TestCase (RoundtripType.PortablePdb, false, false)]
- [TestCase (RoundtripType.PortablePdb, true, false)]
- [TestCase (RoundtripType.PortablePdb, true, true)]
- public void RemoveWithSymbolRoundtrip (RoundtripType roundtripType, bool forceUnresolved, bool reverseScopes)
+ [TestCase (RoundtripType.None, false, false, false)]
+ [TestCase (RoundtripType.Pdb, false, false, false)]
+ [TestCase (RoundtripType.Pdb, true, false, false)]
+ [TestCase (RoundtripType.Pdb, true, false, true)]
+ [TestCase (RoundtripType.Pdb, true, true, false)]
+ [TestCase (RoundtripType.PortablePdb, false, false, false)]
+ [TestCase (RoundtripType.PortablePdb, true, false, false)]
+ [TestCase (RoundtripType.PortablePdb, true, false, true)]
+ [TestCase (RoundtripType.PortablePdb, true, true, false)]
+ public void RemoveWithSymbolRoundtrip (RoundtripType roundtripType, bool forceUnresolved, bool reverseScopes, bool padIL)
{
- var methodBody = CreateTestMethodWithLocalScopes ();
+ var methodBody = CreateTestMethodWithLocalScopes (padIL);
methodBody = RoundtripMethodBody (methodBody, roundtripType, forceUnresolved, reverseScopes);
var il = methodBody.GetILProcessor ();
@@ -200,16 +204,18 @@ namespace Mono.Cecil.Tests {
methodBody.Method.Module.Dispose ();
}
- [TestCase (RoundtripType.None, false, false)]
- [TestCase (RoundtripType.Pdb, false, false)]
- [TestCase (RoundtripType.Pdb, true, false)]
- [TestCase (RoundtripType.Pdb, true, true)]
- [TestCase (RoundtripType.PortablePdb, false, false)]
- [TestCase (RoundtripType.PortablePdb, true, false)]
- [TestCase (RoundtripType.PortablePdb, true, true)]
- public void ReplaceWithSymbolRoundtrip (RoundtripType roundtripType, bool forceUnresolved, bool reverseScopes)
+ [TestCase (RoundtripType.None, false, false, false)]
+ [TestCase (RoundtripType.Pdb, false, false, false)]
+ [TestCase (RoundtripType.Pdb, true, false, false)]
+ [TestCase (RoundtripType.Pdb, true, false, true)]
+ [TestCase (RoundtripType.Pdb, true, true, false)]
+ [TestCase (RoundtripType.PortablePdb, false, false, false)]
+ [TestCase (RoundtripType.PortablePdb, true, false, false)]
+ [TestCase (RoundtripType.PortablePdb, true, false, true)]
+ [TestCase (RoundtripType.PortablePdb, true, true, false)]
+ public void ReplaceWithSymbolRoundtrip (RoundtripType roundtripType, bool forceUnresolved, bool reverseScopes, bool padIL)
{
- var methodBody = CreateTestMethodWithLocalScopes ();
+ var methodBody = CreateTestMethodWithLocalScopes (padIL);
methodBody = RoundtripMethodBody (methodBody, roundtripType, forceUnresolved, reverseScopes);
var il = methodBody.GetILProcessor ();
@@ -224,16 +230,18 @@ namespace Mono.Cecil.Tests {
methodBody.Method.Module.Dispose ();
}
- [TestCase (RoundtripType.None, false, false)]
- [TestCase (RoundtripType.Pdb, false, false)]
- [TestCase (RoundtripType.Pdb, true, false)]
- [TestCase (RoundtripType.Pdb, true, true)]
- [TestCase (RoundtripType.PortablePdb, false, false)]
- [TestCase (RoundtripType.PortablePdb, true, false)]
- [TestCase (RoundtripType.PortablePdb, true, true)]
- public void EditBodyWithScopesAndSymbolRoundtrip (RoundtripType roundtripType, bool forceUnresolved, bool reverseScopes)
+ [TestCase (RoundtripType.None, false, false, false)]
+ [TestCase (RoundtripType.Pdb, false, false, false)]
+ [TestCase (RoundtripType.Pdb, true, false, false)]
+ [TestCase (RoundtripType.Pdb, true, false, true)]
+ [TestCase (RoundtripType.Pdb, true, true, false)]
+ [TestCase (RoundtripType.PortablePdb, false, false, false)]
+ [TestCase (RoundtripType.PortablePdb, true, false, false)]
+ [TestCase (RoundtripType.PortablePdb, true, false, true)]
+ [TestCase (RoundtripType.PortablePdb, true, true, false)]
+ public void EditBodyWithScopesAndSymbolRoundtrip (RoundtripType roundtripType, bool forceUnresolved, bool reverseScopes, bool padIL)
{
- var methodBody = CreateTestMethodWithLocalScopes ();
+ var methodBody = CreateTestMethodWithLocalScopes (padIL);
methodBody = RoundtripMethodBody (methodBody, roundtripType, forceUnresolved, reverseScopes);
var il = methodBody.GetILProcessor ();
@@ -320,13 +328,16 @@ namespace Mono.Cecil.Tests {
Assert.IsTrue (scope.End.IsEndOfMethod);
}
- static MethodBody CreateTestMethodWithLocalScopes ()
+ static MethodBody CreateTestMethodWithLocalScopes (bool padILWithNulls)
{
var module = ModuleDefinition.CreateModule ("TestILProcessor", ModuleKind.Dll);
var type = new TypeDefinition ("NS", "TestType", TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.Sealed, module.ImportReference (typeof (object)));
module.Types.Add (type);
var methodBody = CreateTestMethod (OpCodes.Nop, OpCodes.Ldloc_0, OpCodes.Nop, OpCodes.Ldloc_1, OpCodes.Nop, OpCodes.Ldloc_2, OpCodes.Nop);
+ if (padILWithNulls)
+ methodBody.Instructions.Capacity += 10;
+
var method = methodBody.Method;
method.ReturnType = module.ImportReference (typeof (void));
type.Methods.Add (method);