diff --git a/src/node_buffer.cc b/src/node_buffer.cc index dda430d5bb8..94081e44dc0 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -666,7 +666,7 @@ void Fill(const FunctionCallbackInfo& args) { } else if (enc == UCS2) { str_length = str_obj->Length() * sizeof(uint16_t); node::TwoByteValue str(env->isolate(), args[1]); - if (IsBigEndian()) + if constexpr (IsBigEndian()) SwapBytes16(reinterpret_cast(&str[0]), str_length); memcpy(ts_obj_data + start, *str, std::min(str_length, fill_length)); @@ -960,7 +960,7 @@ void IndexOfString(const FunctionCallbackInfo& args) { return args.GetReturnValue().Set(-1); } - if (IsBigEndian()) { + if constexpr (IsBigEndian()) { StringBytes::InlineDecoder decoder; if (decoder.Decode(env, needle, enc).IsNothing()) return; const uint16_t* decoded_string = diff --git a/src/node_file.cc b/src/node_file.cc index 7fd63b3a1c6..3d53f84dfbb 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -2262,10 +2262,12 @@ static void WriteString(const FunctionCallbackInfo& args) { auto ext = string->GetExternalOneByteStringResource(); buf = const_cast(ext->data()); len = ext->length(); - } else if (enc == UCS2 && IsLittleEndian() && string->IsExternalTwoByte()) { - auto ext = string->GetExternalStringResource(); - buf = reinterpret_cast(const_cast(ext->data())); - len = ext->length() * sizeof(*ext->data()); + } else if (enc == UCS2 && string->IsExternalTwoByte()) { + if constexpr (IsLittleEndian()) { + auto ext = string->GetExternalStringResource(); + buf = reinterpret_cast(const_cast(ext->data())); + len = ext->length() * sizeof(*ext->data()); + } } } diff --git a/src/node_i18n.cc b/src/node_i18n.cc index d45325954d9..743ea8c872c 100644 --- a/src/node_i18n.cc +++ b/src/node_i18n.cc @@ -111,7 +111,7 @@ MaybeLocal ToBufferEndian(Environment* env, MaybeStackBuffer* buf) { static_assert(sizeof(T) == 1 || sizeof(T) == 2, "Currently only one- or two-byte buffers are supported"); - if (sizeof(T) > 1 && IsBigEndian()) { + if constexpr (sizeof(T) > 1 && IsBigEndian()) { SPREAD_BUFFER_ARG(ret.ToLocalChecked(), retbuf); SwapBytes16(retbuf_data, retbuf_length); } @@ -128,7 +128,7 @@ void CopySourceBuffer(MaybeStackBuffer* dest, dest->AllocateSufficientStorage(length_in_chars); char* dst = reinterpret_cast(**dest); memcpy(dst, data, length); - if (IsBigEndian()) { + if constexpr (IsBigEndian()) { SwapBytes16(dst, length); } } @@ -527,7 +527,7 @@ void ConverterObject::Decode(const FunctionCallbackInfo& args) { char* value = reinterpret_cast(output) + beginning; - if (IsBigEndian()) { + if constexpr (IsBigEndian()) { SwapBytes16(value, length); } diff --git a/src/string_bytes.cc b/src/string_bytes.cc index 6b9d1b41a9f..94e60790232 100644 --- a/src/string_bytes.cc +++ b/src/string_bytes.cc @@ -339,8 +339,7 @@ size_t StringBytes::Write(Isolate* isolate, // the Buffer, so we need to reorder on BE platforms. See // https://nodejs.org/api/buffer.html regarding Node's "ucs2" // encoding specification - if (IsBigEndian()) - SwapBytes16(buf, nbytes); + if constexpr (IsBigEndian()) SwapBytes16(buf, nbytes); break; } @@ -756,7 +755,7 @@ MaybeLocal StringBytes::Encode(Isolate* isolate, case UCS2: { size_t str_len = buflen / 2; - if (IsBigEndian()) { + if constexpr (IsBigEndian()) { uint16_t* dst = node::UncheckedMalloc(str_len); if (str_len != 0 && dst == nullptr) { *error = node::ERR_MEMORY_ALLOCATION_FAILED(isolate); @@ -803,7 +802,7 @@ MaybeLocal StringBytes::Encode(Isolate* isolate, // Buffer, so we need to reorder on BE platforms. See // https://nodejs.org/api/buffer.html regarding Node's "ucs2" // encoding specification - if (IsBigEndian()) { + if constexpr (IsBigEndian()) { uint16_t* dst = node::UncheckedMalloc(buflen); if (dst == nullptr) { *error = node::ERR_MEMORY_ALLOCATION_FAILED(isolate); diff --git a/src/util.h b/src/util.h index 7ac2b3efea3..e50930aa7ab 100644 --- a/src/util.h +++ b/src/util.h @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -778,24 +779,16 @@ inline v8::MaybeLocal ToV8Value(v8::Local context, .Check(); \ } while (0) -enum class Endianness { LITTLE, BIG }; - -inline Endianness GetEndianness() { - // Constant-folded by the compiler. - const union { - uint8_t u8[2]; - uint16_t u16; - } u = {{1, 0}}; - return u.u16 == 1 ? Endianness::LITTLE : Endianness::BIG; +constexpr inline bool IsLittleEndian() { + return std::endian::native == std::endian::little; } -inline bool IsLittleEndian() { - return GetEndianness() == Endianness::LITTLE; +constexpr inline bool IsBigEndian() { + return std::endian::native == std::endian::big; } -inline bool IsBigEndian() { - return GetEndianness() == Endianness::BIG; -} +static_assert(IsLittleEndian() || IsBigEndian(), + "Node.js does not support mixed-endian systems"); // Round up a to the next highest multiple of b. template