Skip to content

Commit

Permalink
Fix invalid IL code in Util.ElemOffset
Browse files Browse the repository at this point in the history
  • Loading branch information
ocoanet committed Mar 21, 2019
1 parent 64c8948 commit e58c9f4
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 8 deletions.
18 changes: 17 additions & 1 deletion src/Disruptor.Tests/Utils/UtilTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using System;
using System.Linq;
using Disruptor.Tests.Support;
using NUnit.Framework;

namespace Disruptor.Tests.Utils
Expand Down Expand Up @@ -36,5 +39,18 @@ public void ShouldReturnLongMaxWhenNoEventProcessors()

Assert.AreEqual(long.MaxValue, Util.GetMinimumSequence(sequences));
}

[Test]
public void ShouldReadArrayElement()
{
var array = Enumerable.Range(0, 100)
.Select(x => new LongEvent())
.ToArray();

for (var index = 0; index < array.Length; index++)
{
Assert.AreEqual(array[index], Util.Read<LongEvent>(array, index));
}
}
}
}
}
30 changes: 23 additions & 7 deletions src/Disruptor/Util/Util.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Disruptor
/// </summary>
internal static class Util
{
private static readonly int _offsetToArrayData = ElemOffset(new object[1]);
private static readonly int _offsetToArrayData = OffsetToArrayData();

/// <summary>
/// Calculate the next power of 2, greater than or equal to x.
Expand Down Expand Up @@ -42,6 +42,7 @@ public static int Log2(int i)
{
++r;
}

return r;
}

Expand All @@ -68,6 +69,7 @@ public static long GetMinimumSequence(ISequence[] sequences, long minimum = long
var sequence = sequences[i].Value;
minimum = Math.Min(minimum, sequence);
}

return minimum;
}

Expand Down Expand Up @@ -113,15 +115,29 @@ public static T Read<T>(object array, int index)
return IL.Return<T>();
}

private static int ElemOffset(object[] arr)
private static int OffsetToArrayData()
{
var array = new object[1];

return (int)ElemOffset(array, ref array[0]);
}

private static IntPtr ElemOffset(object origin, ref object target)
{
Ldarg(nameof(arr));
Ldc_I4_0();
Ldelema(typeof(object));
Ldarg(nameof(arr));
IL.DeclareLocals(
false,
typeof(byte).MakeByRefType()
);

Ldarg(nameof(target));

Ldarg(nameof(origin)); // load the object
Stloc_0(); // convert the object pointer to a byref
Ldloc_0(); // load the object pointer as a byref

Sub();

return IL.Return<int>();
return IL.Return<IntPtr>();
}
}
}

0 comments on commit e58c9f4

Please sign in to comment.