1
0
mirror of https://github.com/SerenityOS/serenity synced 2024-07-09 12:00:49 +00:00

AK: Add a 'HostIsLittleEndian' constant and use it instead of BYTE_ORDER

Previously we were using the preprocessor everywhere we needed this
constant, so let's move away from that and use a constexpr constant.
This commit is contained in:
Ali Mohammad Pur 2023-06-12 13:28:25 +03:30 committed by Ali Mohammad Pur
parent b3a295a5bd
commit 94f5389934
3 changed files with 26 additions and 27 deletions

View File

@ -35,39 +35,40 @@
#endif #endif
namespace AK { namespace AK {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
inline constexpr static bool HostIsLittleEndian = true;
#else
inline constexpr static bool HostIsLittleEndian = false;
#endif
template<typename T> template<typename T>
ALWAYS_INLINE constexpr T convert_between_host_and_little_endian(T value) ALWAYS_INLINE constexpr T convert_between_host_and_little_endian(T value)
{ {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ if constexpr (HostIsLittleEndian || sizeof(T) == 1)
return value;
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
if constexpr (sizeof(T) == 8)
return static_cast<T>(__builtin_bswap64(static_cast<u64>(value)));
if constexpr (sizeof(T) == 4)
return static_cast<T>(__builtin_bswap32(static_cast<u32>(value)));
if constexpr (sizeof(T) == 2)
return static_cast<T>(__builtin_bswap16(static_cast<u16>(value)));
if constexpr (sizeof(T) == 1)
return value; return value;
#endif else if constexpr (sizeof(T) == 8)
return static_cast<T>(__builtin_bswap64(static_cast<u64>(value)));
else if constexpr (sizeof(T) == 4)
return static_cast<T>(__builtin_bswap32(static_cast<u32>(value)));
else if constexpr (sizeof(T) == 2)
return static_cast<T>(__builtin_bswap16(static_cast<u16>(value)));
else
static_assert(DependentFalse<T>, "Cannot byte-swap values larger than 64-bits");
} }
template<typename T> template<typename T>
ALWAYS_INLINE constexpr T convert_between_host_and_big_endian(T value) ALWAYS_INLINE constexpr T convert_between_host_and_big_endian(T value)
{ {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ if constexpr (sizeof(T) == 1 || !HostIsLittleEndian)
if constexpr (sizeof(T) == 8)
return static_cast<T>(__builtin_bswap64(static_cast<u64>(value)));
if constexpr (sizeof(T) == 4)
return static_cast<T>(__builtin_bswap32(static_cast<u32>(value)));
if constexpr (sizeof(T) == 2)
return static_cast<T>(__builtin_bswap16(static_cast<u16>(value)));
if constexpr (sizeof(T) == 1)
return value; return value;
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ else if constexpr (sizeof(T) == 8)
return value; return static_cast<T>(__builtin_bswap64(static_cast<u64>(value)));
#endif else if constexpr (sizeof(T) == 4)
return static_cast<T>(__builtin_bswap32(static_cast<u32>(value)));
else if constexpr (sizeof(T) == 2)
return static_cast<T>(__builtin_bswap16(static_cast<u16>(value)));
else
static_assert(DependentFalse<T>, "Cannot byte-swap values larger than 64-bits");
} }
template<typename T> template<typename T>

View File

@ -176,10 +176,8 @@ static constexpr auto max_representable_power_of_ten_in_u64 = 19;
static_assert(1e19 <= static_cast<double>(NumericLimits<u64>::max())); static_assert(1e19 <= static_cast<double>(NumericLimits<u64>::max()));
static_assert(1e20 >= static_cast<double>(NumericLimits<u64>::max())); static_assert(1e20 >= static_cast<double>(NumericLimits<u64>::max()));
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ static_assert(HostIsLittleEndian, "Float parsing currently assumes little endian, this fact is only used in fast parsing of 8 digits at a time"
# error Float parsing currently assumes little endian, this fact is only used in fast parsing of 8 digits at a time \ "\nyou _should_ only need to change read eight_digits to make this big endian compatible.");
you _should_ only need to change read eight_digits to make this big endian compatible.
#endif
constexpr u64 read_eight_digits(char const* string) constexpr u64 read_eight_digits(char const* string)
{ {
u64 val; u64 val;

View File

@ -225,7 +225,7 @@ static ThrowCompletionOr<Value> atomic_compare_exchange_impl(VM& vm, TypedArrayB
// 9. Let elementSize be TypedArrayElementSize(typedArray). // 9. Let elementSize be TypedArrayElementSize(typedArray).
// 10. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record. // 10. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
constexpr bool is_little_endian = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__; constexpr bool is_little_endian = AK::HostIsLittleEndian;
// 11. Let expectedBytes be NumericToRawBytes(elementType, expected, isLittleEndian). // 11. Let expectedBytes be NumericToRawBytes(elementType, expected, isLittleEndian).
auto expected_bytes = MUST_OR_THROW_OOM(numeric_to_raw_bytes<T>(vm, expected, is_little_endian)); auto expected_bytes = MUST_OR_THROW_OOM(numeric_to_raw_bytes<T>(vm, expected, is_little_endian));