Bit32Helper.cs 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. using System.Runtime.CompilerServices;
  2. namespace Lua.Standard.Bitwise;
  3. internal static class Bit32Helper
  4. {
  5. static readonly uint[] Masks = [
  6. 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF,
  7. 0x1FF, 0x3FF, 0x7FF, 0xFFF,
  8. 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF,
  9. 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF,
  10. 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF,
  11. 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF,
  12. 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF,
  13. ];
  14. static readonly double Bit32 = 4294967296;
  15. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  16. public static uint ToUInt32(double d)
  17. {
  18. var x = (int)Math.IEEERemainder(d, Bit32);
  19. return (uint)x;
  20. }
  21. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  22. public static int ToInt32(double d)
  23. {
  24. d = Math.IEEERemainder(d, Bit32);
  25. return (int)d;
  26. }
  27. public static uint GetNBitMask(int bits)
  28. {
  29. if (bits <= 0) return 0;
  30. if (bits >= 32) return Masks[31];
  31. return Masks[bits - 1];
  32. }
  33. public static void ValidateFieldAndWidth(LuaState state, LuaFunction function, int argumentId, int pos, int width)
  34. {
  35. if (pos > 31 || (pos + width) > 31)
  36. throw new LuaRuntimeException(state.GetTraceback(), "trying to access non-existent bits");
  37. if (pos < 0)
  38. throw new LuaRuntimeException(state.GetTraceback(), $"bad argument #{argumentId} to '{function.Name}' (field cannot be negative)");
  39. if (width <= 0)
  40. throw new LuaRuntimeException(state.GetTraceback(), "bad argument #{argumentId} to '{function.Name}' (width must be positive)");
  41. }
  42. }