mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
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: https://github.com/nodejs/node/pull/44411 PR-URL: https://github.com/nodejs/node/pull/52974 Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
0cbbab9a4d
commit
177b8b957b
@ -666,7 +666,7 @@ void Fill(const FunctionCallbackInfo<Value>& 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<char*>(&str[0]), str_length);
|
||||
|
||||
memcpy(ts_obj_data + start, *str, std::min(str_length, fill_length));
|
||||
@ -960,7 +960,7 @@ void IndexOfString(const FunctionCallbackInfo<Value>& 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 =
|
||||
|
@ -2262,10 +2262,12 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
|
||||
auto ext = string->GetExternalOneByteStringResource();
|
||||
buf = const_cast<char*>(ext->data());
|
||||
len = ext->length();
|
||||
} else if (enc == UCS2 && IsLittleEndian() && string->IsExternalTwoByte()) {
|
||||
auto ext = string->GetExternalStringResource();
|
||||
buf = reinterpret_cast<char*>(const_cast<uint16_t*>(ext->data()));
|
||||
len = ext->length() * sizeof(*ext->data());
|
||||
} else if (enc == UCS2 && string->IsExternalTwoByte()) {
|
||||
if constexpr (IsLittleEndian()) {
|
||||
auto ext = string->GetExternalStringResource();
|
||||
buf = reinterpret_cast<char*>(const_cast<uint16_t*>(ext->data()));
|
||||
len = ext->length() * sizeof(*ext->data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ MaybeLocal<Object> ToBufferEndian(Environment* env, MaybeStackBuffer<T>* 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<UChar>* dest,
|
||||
dest->AllocateSufficientStorage(length_in_chars);
|
||||
char* dst = reinterpret_cast<char*>(**dest);
|
||||
memcpy(dst, data, length);
|
||||
if (IsBigEndian()) {
|
||||
if constexpr (IsBigEndian()) {
|
||||
SwapBytes16(dst, length);
|
||||
}
|
||||
}
|
||||
@ -527,7 +527,7 @@ void ConverterObject::Decode(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
char* value = reinterpret_cast<char*>(output) + beginning;
|
||||
|
||||
if (IsBigEndian()) {
|
||||
if constexpr (IsBigEndian()) {
|
||||
SwapBytes16(value, length);
|
||||
}
|
||||
|
||||
|
@ -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<Value> StringBytes::Encode(Isolate* isolate,
|
||||
|
||||
case UCS2: {
|
||||
size_t str_len = buflen / 2;
|
||||
if (IsBigEndian()) {
|
||||
if constexpr (IsBigEndian()) {
|
||||
uint16_t* dst = node::UncheckedMalloc<uint16_t>(str_len);
|
||||
if (str_len != 0 && dst == nullptr) {
|
||||
*error = node::ERR_MEMORY_ALLOCATION_FAILED(isolate);
|
||||
@ -803,7 +802,7 @@ MaybeLocal<Value> 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<uint16_t>(buflen);
|
||||
if (dst == nullptr) {
|
||||
*error = node::ERR_MEMORY_ALLOCATION_FAILED(isolate);
|
||||
|
21
src/util.h
21
src/util.h
@ -37,6 +37,7 @@
|
||||
#include <cstring>
|
||||
|
||||
#include <array>
|
||||
#include <bit>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
@ -778,24 +779,16 @@ inline v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> 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 <typename T>
|
||||
|
Loading…
Reference in New Issue
Block a user