Use generic math alignment in assert code

This commit is contained in:
Alex Barney 2022-12-13 19:43:24 -07:00
parent df77de365c
commit ff4de7476b
6 changed files with 24 additions and 77 deletions

View file

@ -664,7 +664,7 @@ public static class Assert
} }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// In range T // In range
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
private static void InRangeImpl<T>(AssertionType assertionType, T value, T lower, T upper, string valueText, private static void InRangeImpl<T>(AssertionType assertionType, T value, T lower, T upper, string valueText,
@ -721,7 +721,7 @@ public static class Assert
} }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// Within min-max T // Within min-max
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
private static void WithinMinMaxImpl<T>(AssertionType assertionType, T value, T min, T max, string valueText, private static void WithinMinMaxImpl<T>(AssertionType assertionType, T value, T min, T max, string valueText,
@ -1174,11 +1174,11 @@ public static class Assert
} }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// Aligned long // Aligned
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
private static void AlignedImpl(AssertionType assertionType, long value, int alignment, string valueText, private static void AlignedImpl<T>(AssertionType assertionType, T value, int alignment, string valueText,
string alignmentText, string functionName, string fileName, int lineNumber) string alignmentText, string functionName, string fileName, int lineNumber) where T : IBinaryNumber<T>
{ {
if (AssertImpl.IsAligned(value, alignment)) if (AssertImpl.IsAligned(value, alignment))
return; return;
@ -1188,86 +1188,39 @@ public static class Assert
} }
[Conditional(AssertCondition)] [Conditional(AssertCondition)]
public static void Aligned(long value, int alignment, public static void Aligned<T>(T value, int alignment,
[CallerArgumentExpression(nameof(value))] string valueText = "", [CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(alignment))] string alignmentText = "", [CallerArgumentExpression(nameof(alignment))] string alignmentText = "",
[CallerMemberName] string functionName = "", [CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "", [CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0) [CallerLineNumber] int lineNumber = 0)
where T : IBinaryNumber<T>
{ {
AlignedImpl(AssertionType.UserAssert, value, alignment, valueText, alignmentText, functionName, fileName, AlignedImpl(AssertionType.UserAssert, value, alignment, valueText, alignmentText, functionName, fileName,
lineNumber); lineNumber);
} }
[Conditional(AssertCondition)] [Conditional(AssertCondition)]
internal static void SdkAligned(long value, int alignment, internal static void SdkAligned<T>(T value, int alignment,
[CallerArgumentExpression(nameof(value))] string valueText = "", [CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(alignment))] string alignmentText = "", [CallerArgumentExpression(nameof(alignment))] string alignmentText = "",
[CallerMemberName] string functionName = "", [CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "", [CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0) [CallerLineNumber] int lineNumber = 0)
where T : IBinaryNumber<T>
{ {
AlignedImpl(AssertionType.SdkAssert, value, alignment, valueText, alignmentText, functionName, fileName, AlignedImpl(AssertionType.SdkAssert, value, alignment, valueText, alignmentText, functionName, fileName,
lineNumber); lineNumber);
} }
[Conditional(AssertCondition)] [Conditional(AssertCondition)]
internal static void SdkRequiresAligned(long value, int alignment, internal static void SdkRequiresAligned<T>(T value, int alignment,
[CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(alignment))] string alignmentText = "",
[CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0)
{
AlignedImpl(AssertionType.SdkRequires, value, alignment, valueText, alignmentText, functionName, fileName,
lineNumber);
}
// ---------------------------------------------------------------------
// Aligned ulong
// ---------------------------------------------------------------------
private static void AlignedImpl(AssertionType assertionType, ulong value, int alignment, string valueText,
string alignmentText, string functionName, string fileName, int lineNumber)
{
if (AssertImpl.IsAligned(value, alignment))
return;
AssertImpl.InvokeAssertionAligned(assertionType, value, alignment, valueText, alignmentText, functionName, fileName,
lineNumber);
}
[Conditional(AssertCondition)]
public static void Aligned(ulong value, int alignment,
[CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(alignment))] string alignmentText = "",
[CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0)
{
AlignedImpl(AssertionType.UserAssert, value, alignment, valueText, alignmentText, functionName, fileName,
lineNumber);
}
[Conditional(AssertCondition)]
internal static void SdkAligned(ulong value, int alignment,
[CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(alignment))] string alignmentText = "",
[CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0)
{
AlignedImpl(AssertionType.SdkAssert, value, alignment, valueText, alignmentText, functionName, fileName,
lineNumber);
}
[Conditional(AssertCondition)]
internal static void SdkRequiresAligned(ulong value, int alignment,
[CallerArgumentExpression(nameof(value))] string valueText = "", [CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(alignment))] string alignmentText = "", [CallerArgumentExpression(nameof(alignment))] string alignmentText = "",
[CallerMemberName] string functionName = "", [CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "", [CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0) [CallerLineNumber] int lineNumber = 0)
where T : IBinaryNumber<T>
{ {
AlignedImpl(AssertionType.SdkRequires, value, alignment, valueText, alignmentText, functionName, fileName, AlignedImpl(AssertionType.SdkRequires, value, alignment, valueText, alignmentText, functionName, fileName,
lineNumber); lineNumber);

View file

@ -240,12 +240,7 @@ internal static class AssertImpl
return lhs.CompareTo(rhs) >= 0; return lhs.CompareTo(rhs) >= 0;
} }
public static bool IsAligned(long value, int alignment) public static bool IsAligned<T>(T value, int alignment) where T : IBinaryNumber<T>
{
return Alignment.IsAligned(value, (uint)alignment);
}
public static bool IsAligned(ulong value, int alignment)
{ {
return Alignment.IsAligned(value, (uint)alignment); return Alignment.IsAligned(value, (uint)alignment);
} }

View file

@ -35,7 +35,7 @@ public class AesXtsStorage : IStorage
{ {
Assert.Equal(outIv.Length, IvSize); Assert.Equal(outIv.Length, IvSize);
Assert.SdkRequiresGreaterEqual(offset, 0); Assert.SdkRequiresGreaterEqual(offset, 0);
Assert.SdkRequiresAligned((ulong)blockSize, AesBlockSize); Assert.SdkRequiresAligned(blockSize, AesBlockSize);
BinaryPrimitives.WriteInt64BigEndian(outIv.Slice(sizeof(long)), offset / blockSize); BinaryPrimitives.WriteInt64BigEndian(outIv.Slice(sizeof(long)), offset / blockSize);
} }
@ -50,7 +50,7 @@ public class AesXtsStorage : IStorage
Assert.SdkRequiresEqual(KeySize, key1.Length); Assert.SdkRequiresEqual(KeySize, key1.Length);
Assert.SdkRequiresEqual(KeySize, key2.Length); Assert.SdkRequiresEqual(KeySize, key2.Length);
Assert.SdkRequiresEqual(IvSize, iv.Length); Assert.SdkRequiresEqual(IvSize, iv.Length);
Assert.SdkRequiresAligned((ulong)blockSize, AesBlockSize); Assert.SdkRequiresAligned(blockSize, AesBlockSize);
key1.CopyTo(_key1.Items); key1.CopyTo(_key1.Items);
key2.CopyTo(_key2.Items); key2.CopyTo(_key2.Items);
@ -68,7 +68,7 @@ public class AesXtsStorage : IStorage
Assert.SdkRequiresEqual(KeySize, key1.Length); Assert.SdkRequiresEqual(KeySize, key1.Length);
Assert.SdkRequiresEqual(KeySize, key2.Length); Assert.SdkRequiresEqual(KeySize, key2.Length);
Assert.SdkRequiresEqual(IvSize, iv.Length); Assert.SdkRequiresEqual(IvSize, iv.Length);
Assert.SdkRequiresAligned((ulong)blockSize, AesBlockSize); Assert.SdkRequiresAligned(blockSize, AesBlockSize);
key1.CopyTo(_key1.Items); key1.CopyTo(_key1.Items);
key2.CopyTo(_key2.Items); key2.CopyTo(_key2.Items);

View file

@ -431,7 +431,7 @@ public class BufferedStorage : IStorage
Assert.SdkRequiresEqual(_prevIndex, InvalidIndex); Assert.SdkRequiresEqual(_prevIndex, InvalidIndex);
Assert.SdkRequires(!IsValid()); Assert.SdkRequires(!IsValid());
Assert.SdkRequires(!_isDirty); Assert.SdkRequires(!_isDirty);
Assert.SdkRequiresAligned((ulong)offset, (int)_bufferedStorage._blockSize); Assert.SdkRequiresAligned(offset, (int)_bufferedStorage._blockSize);
// Make sure this Cache has an allocated buffer // Make sure this Cache has an allocated buffer
if (_memoryRange.IsNull) if (_memoryRange.IsNull)

View file

@ -221,8 +221,8 @@ public unsafe class FileSystemBuddyHeap : IDisposable
public Result Initialize(UIntPtr address, nuint size, nuint blockSize, int orderMax) public Result Initialize(UIntPtr address, nuint size, nuint blockSize, int orderMax)
{ {
Assert.SdkRequires(FreeLists == null); Assert.SdkRequires(FreeLists == null);
Assert.SdkRequiresNotEqual(address, UIntPtr.Zero); Assert.SdkRequiresNotEqual(address, nuint.Zero);
Assert.SdkRequiresAligned(address.ToUInt64(), (int)BufferAlignment); Assert.SdkRequiresAligned(address, (int)BufferAlignment);
Assert.SdkRequiresGreaterEqual(blockSize, BlockSizeMin); Assert.SdkRequiresGreaterEqual(blockSize, BlockSizeMin);
Assert.SdkRequires(BitUtil.IsPowerOfTwo(blockSize)); Assert.SdkRequires(BitUtil.IsPowerOfTwo(blockSize));
Assert.SdkRequiresGreaterEqual(size, blockSize); Assert.SdkRequiresGreaterEqual(size, blockSize);
@ -240,7 +240,7 @@ public unsafe class FileSystemBuddyHeap : IDisposable
// Determine page sizes // Determine page sizes
nuint maxPageSize = BlockSize << OrderMax; nuint maxPageSize = BlockSize << OrderMax;
nuint maxPageCount = (nuint)Alignment.AlignUp(HeapSize, (uint)maxPageSize) / maxPageSize; nuint maxPageCount = (nuint)Alignment.AlignUp(HeapSize, (uint)maxPageSize) / maxPageSize;
Assert.SdkGreater((int)maxPageCount, 0); Assert.SdkGreater(maxPageCount, nuint.Zero);
// Setup the free lists // Setup the free lists
if (ExternalFreeLists != null) if (ExternalFreeLists != null)
@ -539,8 +539,8 @@ public unsafe class FileSystemBuddyHeap : IDisposable
var address = new UIntPtr(pageEntry); var address = new UIntPtr(pageEntry);
Assert.SdkRequiresGreaterEqual(address, HeapStart); Assert.SdkRequiresGreaterEqual(address, HeapStart);
Assert.SdkRequiresLess((nuint)address, HeapStart + HeapSize); Assert.SdkRequiresLess(address, HeapStart + HeapSize);
Assert.SdkRequiresAligned((nuint)address - HeapStart, (int)GetBlockSize()); Assert.SdkRequiresAligned(address - HeapStart, (int)GetBlockSize());
return address; return address;
} }
@ -548,10 +548,10 @@ public unsafe class FileSystemBuddyHeap : IDisposable
private PageEntry* GetPageEntryFromAddress(UIntPtr address) private PageEntry* GetPageEntryFromAddress(UIntPtr address)
{ {
Assert.SdkRequiresGreaterEqual(address, HeapStart); Assert.SdkRequiresGreaterEqual(address, HeapStart);
Assert.SdkRequiresLess((nuint)address, HeapStart + HeapSize); Assert.SdkRequiresLess(address, HeapStart + HeapSize);
ulong blockStart = (ulong)HeapStart + ulong blockStart = (ulong)HeapStart +
Alignment.AlignDown((nuint)address - HeapStart, (uint)GetBlockSize()); Alignment.AlignDown(address - HeapStart, (uint)GetBlockSize());
return (PageEntry*)blockStart; return (PageEntry*)blockStart;
} }
@ -559,7 +559,7 @@ public unsafe class FileSystemBuddyHeap : IDisposable
{ {
var address = (nuint)pageEntry; var address = (nuint)pageEntry;
Assert.SdkRequiresGreaterEqual(address, (nuint)HeapStart); Assert.SdkRequiresGreaterEqual(address, HeapStart);
Assert.SdkRequiresLess(address, HeapStart + HeapSize); Assert.SdkRequiresLess(address, HeapStart + HeapSize);
Assert.SdkRequiresAligned(address - HeapStart, (int)GetBlockSize()); Assert.SdkRequiresAligned(address - HeapStart, (int)GetBlockSize());

View file

@ -5,7 +5,6 @@ namespace LibHac.Util;
public static class BitUtil public static class BitUtil
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsPowerOfTwo<T>(T value) where T : IBitwiseOperators<T, T, T>, INumberBase<T> public static bool IsPowerOfTwo<T>(T value) where T : IBitwiseOperators<T, T, T>, INumberBase<T>
{ {