Skip to content

Commit 621e102

Browse files
tniesseneliphazbouye
authored andcommitted
src: convert all endian checks to constexpr
This is finally possible in C++20 without having to rely on compiler-defined macros, assuming none of our supported platforms are mixed-endian. Refs: nodejs#44411 PR-URL: nodejs#52974 Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent b2a2a4a commit 621e102

File tree

5 files changed

+21
-27
lines changed

5 files changed

+21
-27
lines changed

src/node_buffer.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ void Fill(const FunctionCallbackInfo<Value>& args) {
666666
} else if (enc == UCS2) {
667667
str_length = str_obj->Length() * sizeof(uint16_t);
668668
node::TwoByteValue str(env->isolate(), args[1]);
669-
if (IsBigEndian())
669+
if constexpr (IsBigEndian())
670670
SwapBytes16(reinterpret_cast<char*>(&str[0]), str_length);
671671

672672
memcpy(ts_obj_data + start, *str, std::min(str_length, fill_length));
@@ -960,7 +960,7 @@ void IndexOfString(const FunctionCallbackInfo<Value>& args) {
960960
return args.GetReturnValue().Set(-1);
961961
}
962962

963-
if (IsBigEndian()) {
963+
if constexpr (IsBigEndian()) {
964964
StringBytes::InlineDecoder decoder;
965965
if (decoder.Decode(env, needle, enc).IsNothing()) return;
966966
const uint16_t* decoded_string =

src/node_file.cc

+6-4
Original file line numberDiff line numberDiff line change
@@ -2262,10 +2262,12 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
22622262
auto ext = string->GetExternalOneByteStringResource();
22632263
buf = const_cast<char*>(ext->data());
22642264
len = ext->length();
2265-
} else if (enc == UCS2 && IsLittleEndian() && string->IsExternalTwoByte()) {
2266-
auto ext = string->GetExternalStringResource();
2267-
buf = reinterpret_cast<char*>(const_cast<uint16_t*>(ext->data()));
2268-
len = ext->length() * sizeof(*ext->data());
2265+
} else if (enc == UCS2 && string->IsExternalTwoByte()) {
2266+
if constexpr (IsLittleEndian()) {
2267+
auto ext = string->GetExternalStringResource();
2268+
buf = reinterpret_cast<char*>(const_cast<uint16_t*>(ext->data()));
2269+
len = ext->length() * sizeof(*ext->data());
2270+
}
22692271
}
22702272
}
22712273

src/node_i18n.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ MaybeLocal<Object> ToBufferEndian(Environment* env, MaybeStackBuffer<T>* buf) {
111111

112112
static_assert(sizeof(T) == 1 || sizeof(T) == 2,
113113
"Currently only one- or two-byte buffers are supported");
114-
if (sizeof(T) > 1 && IsBigEndian()) {
114+
if constexpr (sizeof(T) > 1 && IsBigEndian()) {
115115
SPREAD_BUFFER_ARG(ret.ToLocalChecked(), retbuf);
116116
SwapBytes16(retbuf_data, retbuf_length);
117117
}
@@ -128,7 +128,7 @@ void CopySourceBuffer(MaybeStackBuffer<UChar>* dest,
128128
dest->AllocateSufficientStorage(length_in_chars);
129129
char* dst = reinterpret_cast<char*>(**dest);
130130
memcpy(dst, data, length);
131-
if (IsBigEndian()) {
131+
if constexpr (IsBigEndian()) {
132132
SwapBytes16(dst, length);
133133
}
134134
}
@@ -527,7 +527,7 @@ void ConverterObject::Decode(const FunctionCallbackInfo<Value>& args) {
527527

528528
char* value = reinterpret_cast<char*>(output) + beginning;
529529

530-
if (IsBigEndian()) {
530+
if constexpr (IsBigEndian()) {
531531
SwapBytes16(value, length);
532532
}
533533

src/string_bytes.cc

+3-4
Original file line numberDiff line numberDiff line change
@@ -339,8 +339,7 @@ size_t StringBytes::Write(Isolate* isolate,
339339
// the Buffer, so we need to reorder on BE platforms. See
340340
// https://nodejs.org/api/buffer.html regarding Node's "ucs2"
341341
// encoding specification
342-
if (IsBigEndian())
343-
SwapBytes16(buf, nbytes);
342+
if constexpr (IsBigEndian()) SwapBytes16(buf, nbytes);
344343

345344
break;
346345
}
@@ -756,7 +755,7 @@ MaybeLocal<Value> StringBytes::Encode(Isolate* isolate,
756755

757756
case UCS2: {
758757
size_t str_len = buflen / 2;
759-
if (IsBigEndian()) {
758+
if constexpr (IsBigEndian()) {
760759
uint16_t* dst = node::UncheckedMalloc<uint16_t>(str_len);
761760
if (str_len != 0 && dst == nullptr) {
762761
*error = node::ERR_MEMORY_ALLOCATION_FAILED(isolate);
@@ -803,7 +802,7 @@ MaybeLocal<Value> StringBytes::Encode(Isolate* isolate,
803802
// Buffer, so we need to reorder on BE platforms. See
804803
// https://nodejs.org/api/buffer.html regarding Node's "ucs2"
805804
// encoding specification
806-
if (IsBigEndian()) {
805+
if constexpr (IsBigEndian()) {
807806
uint16_t* dst = node::UncheckedMalloc<uint16_t>(buflen);
808807
if (dst == nullptr) {
809808
*error = node::ERR_MEMORY_ALLOCATION_FAILED(isolate);

src/util.h

+7-14
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <cstring>
3838

3939
#include <array>
40+
#include <bit>
4041
#include <limits>
4142
#include <memory>
4243
#include <set>
@@ -778,24 +779,16 @@ inline v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
778779
.Check(); \
779780
} while (0)
780781

781-
enum class Endianness { LITTLE, BIG };
782-
783-
inline Endianness GetEndianness() {
784-
// Constant-folded by the compiler.
785-
const union {
786-
uint8_t u8[2];
787-
uint16_t u16;
788-
} u = {{1, 0}};
789-
return u.u16 == 1 ? Endianness::LITTLE : Endianness::BIG;
782+
constexpr inline bool IsLittleEndian() {
783+
return std::endian::native == std::endian::little;
790784
}
791785

792-
inline bool IsLittleEndian() {
793-
return GetEndianness() == Endianness::LITTLE;
786+
constexpr inline bool IsBigEndian() {
787+
return std::endian::native == std::endian::big;
794788
}
795789

796-
inline bool IsBigEndian() {
797-
return GetEndianness() == Endianness::BIG;
798-
}
790+
static_assert(IsLittleEndian() || IsBigEndian(),
791+
"Node.js does not support mixed-endian systems");
799792

800793
// Round up a to the next highest multiple of b.
801794
template <typename T>

0 commit comments

Comments
 (0)