public unsafe void BuildPtrTable_LargeRefs() { const int rowSize = 6; const int secondColumnOffset = 2; var table = new byte[] { 0xAA, 0xAA, 0x10, 0x00, 0x05, 0x00, 0xBB, 0xBB, 0x10, 0x00, 0x04, 0x00, 0xCC, 0xCC, 0x10, 0x00, 0x02, 0x01, 0xDD, 0xDD, 0x10, 0x00, 0x02, 0x00, 0xEE, 0xEE, 0x10, 0x00, 0x01, 0x01, }; int rowCount = table.Length / rowSize; fixed (byte* tablePtr = table) { var block = new MemoryBlock(tablePtr, table.Length); Assert.Equal(0x00040010, block.PeekReference(8, smallRefSize: false)); var actual = block.BuildPtrTable(rowCount, rowSize, secondColumnOffset, isReferenceSmall: false); var expected = new int[] { 4, 2, 1, 5, 3 }; Assert.Equal(expected, actual); } }
public unsafe void PeekReference() { var table = new byte[] { 0xff, 0xff, 0xff, 0x00, // offset 0 0xff, 0xff, 0xff, 0x01, // offset 4 0xff, 0xff, 0xff, 0x1f, // offset 8 0xff, 0xff, 0xff, 0x2f, // offset 12 0xff, 0xff, 0xff, 0xff, // offset 16 }; fixed (byte* tablePtr = table) { var block = new MemoryBlock(tablePtr, table.Length); Assert.Equal(0x0000ffff, block.PeekReference(0, smallRefSize: true)); Assert.Equal(0x0000ffff, block.PeekHeapReference(0, smallRefSize: true)); Assert.Equal(0x0000ffffu, block.PeekReferenceUnchecked(0, smallRefSize: true)); Assert.Equal(0x00ffffff, block.PeekReference(0, smallRefSize: false)); Assert.Throws<BadImageFormatException>(() => block.PeekReference(4, smallRefSize: false)); Assert.Throws<BadImageFormatException>(() => block.PeekReference(16, smallRefSize: false)); Assert.Equal(0x1fffffff, block.PeekHeapReference(8, smallRefSize: false)); Assert.Throws<BadImageFormatException>(() => block.PeekHeapReference(12, smallRefSize: false)); Assert.Throws<BadImageFormatException>(() => block.PeekHeapReference(16, smallRefSize: false)); Assert.Equal(0x01ffffffu, block.PeekReferenceUnchecked(4, smallRefSize: false)); Assert.Equal(0x1fffffffu, block.PeekReferenceUnchecked(8, smallRefSize: false)); Assert.Equal(0x2fffffffu, block.PeekReferenceUnchecked(12, smallRefSize: false)); Assert.Equal(0xffffffffu, block.PeekReferenceUnchecked(16, smallRefSize: false)); } }
public unsafe void ValidatePeekReferenceSize() { byte[] buffer = new byte[8] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01 }; fixed (byte* bufferPtr = buffer) { var block = new MemoryBlock(bufferPtr, buffer.Length); // small ref size always fits in 16 bits Assert.Equal(0xFFFF, block.PeekReference(0, smallRefSize: true)); Assert.Equal(0xFFFF, block.PeekReference(4, smallRefSize: true)); Assert.Equal(0xFFFFU, block.PeekTaggedReference(0, smallRefSize: true)); Assert.Equal(0xFFFFU, block.PeekTaggedReference(4, smallRefSize: true)); Assert.Equal(0x01FFU, block.PeekTaggedReference(6, smallRefSize: true)); // large ref size throws on > RIDMask when tagged variant is not used. Assert.Throws<BadImageFormatException>(() => block.PeekReference(0, smallRefSize: false)); Assert.Throws<BadImageFormatException>(() => block.PeekReference(4, smallRefSize: false)); // large ref size does not throw when Tagged variant is used. Assert.Equal(0xFFFFFFFFU, block.PeekTaggedReference(0, smallRefSize: false)); Assert.Equal(0x01FFFFFFU, block.PeekTaggedReference(4, smallRefSize: false)); // bounds check applies in all cases Assert.Throws<BadImageFormatException>(() => block.PeekReference(7, smallRefSize: true)); Assert.Throws<BadImageFormatException>(() => block.PeekReference(5, smallRefSize: false)); } }