mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 16:13:49 +00:00
!3100 Use union instead of memcpy in bit_cast
Merge pull request !3100 from 武万琦/master
This commit is contained in:
commit
30d057f576
@ -22,6 +22,12 @@
|
||||
#include <type_traits>
|
||||
|
||||
namespace panda::ecmascript::base {
|
||||
template <class S, class R>
|
||||
union Data {
|
||||
S src;
|
||||
R dst;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline constexpr uint32_t CountLeadingZeros(T value)
|
||||
{
|
||||
@ -123,11 +129,10 @@ template <class To, class From>
|
||||
inline To bit_cast(const From &src) noexcept // NOLINT(readability-identifier-naming)
|
||||
{
|
||||
static_assert(sizeof(To) == sizeof(From), "size of the types must be equal");
|
||||
To dst;
|
||||
// The use of security functions 'memccpy_s' here will have a greater impact on performance
|
||||
// todo use union instance of memcpy
|
||||
memcpy(&dst, &src, sizeof(To));
|
||||
return dst;
|
||||
// The use of security functions 'memcpy_s' here will have a greater impact on performance
|
||||
Data<From, To> data_;
|
||||
data_.src = src;
|
||||
return data_.dst;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -45,6 +45,18 @@ public:
|
||||
EcmaVM *instance {nullptr};
|
||||
EcmaHandleScope *scope {nullptr};
|
||||
JSThread *thread {nullptr};
|
||||
protected:
|
||||
template <class To, class From>
|
||||
inline To MemoryCast(const From &src) noexcept
|
||||
{
|
||||
static_assert(sizeof(To) == sizeof(From), "size of the types must be equal");
|
||||
To dst;
|
||||
if (memcpy_s(&dst, sizeof(To), &src, sizeof(From)) != EOK) {
|
||||
LOG_FULL(FATAL) << "memcpy_s failed";
|
||||
UNREACHABLE();
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
};
|
||||
|
||||
HWTEST_F_L0(BitHelperTest, CountLeadingZeros_CountTrailingZeros)
|
||||
@ -109,4 +121,54 @@ HWTEST_F_L0(BitHelperTest, CountLeadingZeros64_CountLeadingOnes64)
|
||||
EXPECT_EQ(CountLeadingOnes64(uint64CommonValue2), 0U);
|
||||
EXPECT_EQ(CountLeadingOnes64(uint64MinValue), 0U);
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BitHelperTest, bit_cast)
|
||||
{
|
||||
int8_t int8Value = -128;
|
||||
uint8_t uint8Value = 255;
|
||||
char char8Value = 127;
|
||||
EXPECT_EQ(bit_cast<uint8_t>(int8Value), MemoryCast<uint8_t>(int8Value));
|
||||
EXPECT_EQ(bit_cast<char>(int8Value), MemoryCast<char>(int8Value));
|
||||
EXPECT_EQ(bit_cast<int8_t>(uint8Value), MemoryCast<int8_t>(uint8Value));
|
||||
EXPECT_EQ(bit_cast<char>(uint8Value), MemoryCast<char>(uint8Value));
|
||||
EXPECT_EQ(bit_cast<int8_t>(char8Value), MemoryCast<int8_t>(char8Value));
|
||||
EXPECT_EQ(bit_cast<uint8_t>(char8Value), MemoryCast<uint8_t>(char8Value));
|
||||
|
||||
int16_t int16Value = -32768;
|
||||
uint16_t uint16Value = 65535;
|
||||
char16_t char16Value = 32767;
|
||||
EXPECT_EQ(bit_cast<uint16_t>(int16Value), MemoryCast<uint16_t>(int16Value));
|
||||
EXPECT_EQ(bit_cast<char16_t>(int16Value), MemoryCast<char16_t>(int16Value));
|
||||
EXPECT_EQ(bit_cast<int16_t>(uint16Value), MemoryCast<int16_t>(uint16Value));
|
||||
EXPECT_EQ(bit_cast<char16_t>(uint16Value), MemoryCast<char16_t>(uint16Value));
|
||||
EXPECT_EQ(bit_cast<int16_t>(char16Value), MemoryCast<int16_t>(char16Value));
|
||||
EXPECT_EQ(bit_cast<uint16_t>(char16Value), MemoryCast<uint16_t>(char16Value));
|
||||
|
||||
int32_t int32Value = -2147483648;
|
||||
uint32_t uint32Value = 2147483648;
|
||||
float floatValue = -13.569243f;
|
||||
char32_t char32Value = 2147483648;
|
||||
EXPECT_EQ(bit_cast<uint32_t>(int32Value), MemoryCast<uint32_t>(int32Value));
|
||||
EXPECT_EQ(bit_cast<float>(int32Value), MemoryCast<float>(int32Value));
|
||||
EXPECT_EQ(bit_cast<char32_t>(int32Value), MemoryCast<char32_t>(int32Value));
|
||||
EXPECT_EQ(bit_cast<int32_t>(uint32Value), MemoryCast<int32_t>(uint32Value));
|
||||
EXPECT_EQ(bit_cast<float>(uint32Value), MemoryCast<float>(uint32Value));
|
||||
EXPECT_EQ(bit_cast<char32_t>(uint32Value), MemoryCast<char32_t>(uint32Value));
|
||||
EXPECT_EQ(bit_cast<int32_t>(floatValue), MemoryCast<int32_t>(floatValue));
|
||||
EXPECT_EQ(bit_cast<uint32_t>(floatValue), MemoryCast<uint32_t>(floatValue));
|
||||
EXPECT_EQ(bit_cast<char32_t>(floatValue), MemoryCast<char32_t>(floatValue));
|
||||
EXPECT_EQ(bit_cast<int32_t>(char32Value), MemoryCast<int32_t>(char32Value));
|
||||
EXPECT_EQ(bit_cast<uint32_t>(char32Value), MemoryCast<uint32_t>(char32Value));
|
||||
EXPECT_EQ(bit_cast<float>(char32Value), MemoryCast<float>(char32Value));
|
||||
|
||||
int64_t int64Value = -9223372036854775807LL;
|
||||
uint64_t uint64Value = 9223372036854775808ULL;
|
||||
double doubleValue = -257.93458301390463;
|
||||
EXPECT_EQ(bit_cast<uint64_t>(int64Value), MemoryCast<uint64_t>(int64Value));
|
||||
EXPECT_EQ(bit_cast<double>(int64Value), MemoryCast<double>(int64Value));
|
||||
EXPECT_EQ(bit_cast<int64_t>(uint64Value), MemoryCast<int64_t>(uint64Value));
|
||||
EXPECT_EQ(bit_cast<double>(uint64Value), MemoryCast<double>(uint64Value));
|
||||
EXPECT_EQ(bit_cast<int64_t>(doubleValue), MemoryCast<int64_t>(doubleValue));
|
||||
EXPECT_EQ(bit_cast<uint64_t>(doubleValue), MemoryCast<uint64_t>(doubleValue));
|
||||
}
|
||||
} // namespace panda::test
|
||||
|
@ -492,7 +492,7 @@ JSTaggedValue BuiltinsArrayBuffer::GetValueFromBufferForFloat(uint8_t *block, ui
|
||||
}
|
||||
if (!littleEndian) {
|
||||
uint32_t res = LittleEndianToBigEndian(unionValue.uValue);
|
||||
return GetTaggedDouble(bit_cast<T>(res));
|
||||
return GetTaggedDouble(base::bit_cast<T>(res));
|
||||
}
|
||||
} else if constexpr (std::is_same_v<T, double>) { // NOLINTNEXTLINE(readability-braces-around-statements)
|
||||
unionValue.uValue = *reinterpret_cast<uint64_t *>(block + byteIndex);
|
||||
@ -501,7 +501,7 @@ JSTaggedValue BuiltinsArrayBuffer::GetValueFromBufferForFloat(uint8_t *block, ui
|
||||
}
|
||||
if (!littleEndian) {
|
||||
uint64_t res = LittleEndianToBigEndian64Bit(unionValue.uValue);
|
||||
return GetTaggedDouble(bit_cast<T>(res));
|
||||
return GetTaggedDouble(base::bit_cast<T>(res));
|
||||
}
|
||||
}
|
||||
|
||||
@ -593,11 +593,11 @@ void BuiltinsArrayBuffer::SetValueInBufferForFloat(double val, uint8_t *block, u
|
||||
}
|
||||
if (!littleEndian) {
|
||||
if constexpr (std::is_same_v<T, float>) {
|
||||
uint32_t res = bit_cast<uint32_t>(data);
|
||||
data = bit_cast<T>(LittleEndianToBigEndian(res));
|
||||
uint32_t res = base::bit_cast<uint32_t>(data);
|
||||
data = base::bit_cast<T>(LittleEndianToBigEndian(res));
|
||||
} else if constexpr (std::is_same_v<T, double>) {
|
||||
uint64_t res = bit_cast<uint64_t>(data);
|
||||
data = bit_cast<T>(LittleEndianToBigEndian64Bit(res));
|
||||
uint64_t res = base::bit_cast<uint64_t>(data);
|
||||
data = base::bit_cast<T>(LittleEndianToBigEndian64Bit(res));
|
||||
}
|
||||
}
|
||||
SetTypeData(block, data, byteIndex);
|
||||
|
@ -474,7 +474,7 @@ JSTaggedValue BuiltinsMath::Log2(EcmaRuntimeCallInfo *argv)
|
||||
|
||||
inline bool IsNegZero(double value)
|
||||
{
|
||||
return (value == 0.0 && (bit_cast<uint64_t>(value) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK);
|
||||
return (value == 0.0 && (base::bit_cast<uint64_t>(value) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK);
|
||||
}
|
||||
|
||||
// 20.2.2.24
|
||||
|
@ -298,7 +298,7 @@ public:
|
||||
|
||||
ImmValueType ToJSTaggedValueDouble() const
|
||||
{
|
||||
return JSTaggedValue(bit_cast<double>(value_)).GetRawData();
|
||||
return JSTaggedValue(base::bit_cast<double>(value_)).GetRawData();
|
||||
}
|
||||
|
||||
ImmValueType GetValue() const
|
||||
|
@ -255,7 +255,7 @@ GateRef CircuitBuilder::Boolean(bool val)
|
||||
|
||||
GateRef CircuitBuilder::Double(double val)
|
||||
{
|
||||
return GetCircuit()->GetConstantGate(MachineType::F64, bit_cast<int64_t>(val), GateType::NJSValue());
|
||||
return GetCircuit()->GetConstantGate(MachineType::F64, base::bit_cast<int64_t>(val), GateType::NJSValue());
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::HoleConstant()
|
||||
|
@ -1041,7 +1041,7 @@ void LLVMIRBuilder::VisitConstant(GateRef gate, std::bitset<64> value) // 64: bi
|
||||
UNREACHABLE();
|
||||
}
|
||||
} else if (machineType == MachineType::F64) {
|
||||
auto doubleValue = bit_cast<double>(value.to_ullong()); // actual double value
|
||||
auto doubleValue = base::bit_cast<double>(value.to_ullong()); // actual double value
|
||||
llvmValue = LLVMConstReal(LLVMDoubleType(), doubleValue);
|
||||
} else if (machineType == MachineType::I8) {
|
||||
llvmValue = LLVMConstInt(LLVMInt8Type(), value.to_ulong(), 0);
|
||||
|
@ -180,9 +180,10 @@ public:
|
||||
if (dLeft == 0.0 || std::isnan(dLeft)) {
|
||||
return JSTaggedValue(base::NAN_VALUE);
|
||||
}
|
||||
uint64_t flagBit = ((bit_cast<uint64_t>(dLeft)) ^ (bit_cast<uint64_t>(dRight))) &
|
||||
uint64_t flagBit = ((base::bit_cast<uint64_t>(dLeft)) ^ (base::bit_cast<uint64_t>(dRight))) &
|
||||
base::DOUBLE_SIGN_MASK;
|
||||
return JSTaggedValue(bit_cast<double>(flagBit ^ (bit_cast<uint64_t>(base::POSITIVE_INFINITY))));
|
||||
return JSTaggedValue(base::bit_cast<double>(
|
||||
flagBit ^ (base::bit_cast<uint64_t>(base::POSITIVE_INFINITY))));
|
||||
}
|
||||
return JSTaggedValue(dLeft / dRight);
|
||||
}
|
||||
|
@ -63,8 +63,10 @@ JSTaggedValue FastRuntimeStub::FastDiv(JSTaggedValue left, JSTaggedValue right)
|
||||
if (dLeft == 0.0 || std::isnan(dLeft)) {
|
||||
return JSTaggedValue(base::NAN_VALUE);
|
||||
}
|
||||
uint64_t flagBit = ((bit_cast<uint64_t>(dLeft)) ^ (bit_cast<uint64_t>(dRight))) & base::DOUBLE_SIGN_MASK;
|
||||
return JSTaggedValue(bit_cast<double>(flagBit ^ (bit_cast<uint64_t>(base::POSITIVE_INFINITY))));
|
||||
uint64_t flagBit = ((base::bit_cast<uint64_t>(dLeft)) ^ (base::bit_cast<uint64_t>(dRight))) &
|
||||
base::DOUBLE_SIGN_MASK;
|
||||
return JSTaggedValue(base::bit_cast<double>(
|
||||
flagBit ^ (base::bit_cast<uint64_t>(base::POSITIVE_INFINITY))));
|
||||
}
|
||||
return JSTaggedValue(dLeft / dRight);
|
||||
}
|
||||
|
@ -1076,7 +1076,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, const uint8_t
|
||||
}
|
||||
|
||||
HANDLE_OPCODE(FLDAI_IMM64) {
|
||||
auto imm = bit_cast<double>(READ_INST_64_0());
|
||||
auto imm = base::bit_cast<double>(READ_INST_64_0());
|
||||
LOG_INST() << "fldai " << imm;
|
||||
SET_ACC(JSTaggedValue(imm));
|
||||
DISPATCH(FLDAI_IMM64);
|
||||
@ -2028,7 +2028,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, const uint8_t
|
||||
SET_ACC(JSTaggedValue(base::NAN_VALUE));
|
||||
}
|
||||
bool baseZero = doubleBase == 0 &&
|
||||
(bit_cast<uint64_t>(doubleBase) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK;
|
||||
(base::bit_cast<uint64_t>(doubleBase) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK;
|
||||
bool isFinite = std::isfinite(doubleExponent);
|
||||
bool truncEqual = base::NumberHelper::TruncateDouble(doubleExponent) == doubleExponent;
|
||||
bool halfTruncEqual = (base::NumberHelper::TruncateDouble(doubleExponent / 2) + base::HALF) ==
|
||||
|
@ -476,7 +476,7 @@ void InterpreterAssembly::HandleFldaiImm64(
|
||||
JSThread *thread, const uint8_t *pc, JSTaggedType *sp, JSTaggedValue constpool, JSTaggedValue profileTypeInfo,
|
||||
JSTaggedValue acc, int16_t hotnessCounter)
|
||||
{
|
||||
auto imm = bit_cast<double>(READ_INST_64_0());
|
||||
auto imm = base::bit_cast<double>(READ_INST_64_0());
|
||||
LOG_INST() << "fldai " << imm;
|
||||
SET_ACC(JSTaggedValue(imm));
|
||||
DISPATCH(FLDAI_IMM64);
|
||||
@ -1475,7 +1475,7 @@ void InterpreterAssembly::HandleExpImm8V8(
|
||||
SET_ACC(JSTaggedValue(base::NAN_VALUE));
|
||||
}
|
||||
bool baseZero = doubleBase == 0 &&
|
||||
(bit_cast<uint64_t>(doubleBase) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK;
|
||||
(base::bit_cast<uint64_t>(doubleBase) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK;
|
||||
bool isFinite = std::isfinite(doubleExponent);
|
||||
bool truncEqual = base::NumberHelper::TruncateDouble(doubleExponent) == doubleExponent;
|
||||
bool halfTruncEqual = (base::NumberHelper::TruncateDouble(doubleExponent / 2) + base::HALF) ==
|
||||
|
@ -106,7 +106,7 @@ bool JSTaggedValue::WithinInt32() const
|
||||
}
|
||||
|
||||
double doubleValue = GetNumber();
|
||||
if (bit_cast<int64_t>(doubleValue) == bit_cast<int64_t>(-0.0)) {
|
||||
if (base::bit_cast<int64_t>(doubleValue) == base::bit_cast<int64_t>(-0.0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -540,7 +540,7 @@ JSHandle<TaggedArray> LiteralDataExtractor::GetTypeLiteral(JSThread *thread, con
|
||||
JSTaggedValue jt = JSTaggedValue::Null();
|
||||
switch (tag) {
|
||||
case LiteralTag::INTEGER: {
|
||||
jt = JSTaggedValue(bit_cast<int32_t>(std::get<uint32_t>(value)));
|
||||
jt = JSTaggedValue(base::bit_cast<int32_t>(std::get<uint32_t>(value)));
|
||||
break;
|
||||
}
|
||||
case LiteralTag::LITERALARRAY: {
|
||||
|
@ -90,7 +90,8 @@ JSTaggedValue RuntimeStubs::RuntimeExp(JSThread *thread, JSTaggedValue base, JST
|
||||
if (std::abs(doubleBase) == 1 && std::isinf(doubleExponent)) {
|
||||
return JSTaggedValue(base::NAN_VALUE);
|
||||
}
|
||||
if (((doubleBase == 0) && ((bit_cast<uint64_t>(doubleBase)) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK) &&
|
||||
if (((doubleBase == 0) &&
|
||||
((base::bit_cast<uint64_t>(doubleBase)) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK) &&
|
||||
std::isfinite(doubleExponent) && base::NumberHelper::TruncateDouble(doubleExponent) == doubleExponent &&
|
||||
base::NumberHelper::TruncateDouble(doubleExponent / 2) + base::HALF == (doubleExponent / 2)) { // 2: half
|
||||
if (doubleExponent > 0) {
|
||||
@ -1502,8 +1503,8 @@ JSTaggedValue RuntimeStubs::RuntimeDiv2(JSThread *thread, const JSHandle<JSTagge
|
||||
if (dLeft == 0 || std::isnan(dLeft)) {
|
||||
return JSTaggedValue(base::NAN_VALUE);
|
||||
}
|
||||
bool positive = (((bit_cast<uint64_t>(dRight)) & base::DOUBLE_SIGN_MASK) ==
|
||||
((bit_cast<uint64_t>(dLeft)) & base::DOUBLE_SIGN_MASK));
|
||||
bool positive = (((base::bit_cast<uint64_t>(dRight)) & base::DOUBLE_SIGN_MASK) ==
|
||||
((base::bit_cast<uint64_t>(dLeft)) & base::DOUBLE_SIGN_MASK));
|
||||
return JSTaggedValue(positive ? base::POSITIVE_INFINITY : -base::POSITIVE_INFINITY);
|
||||
}
|
||||
return JSTaggedValue(dLeft / dRight);
|
||||
|
@ -430,7 +430,7 @@ DEF_RUNTIME_STUBS(Exp)
|
||||
return JSTaggedValue(base::NAN_VALUE).GetRawData();
|
||||
}
|
||||
if ((doubleBase == 0 &&
|
||||
((bit_cast<uint64_t>(doubleBase)) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK) &&
|
||||
((base::bit_cast<uint64_t>(doubleBase)) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK) &&
|
||||
std::isfinite(doubleExponent) && base::NumberHelper::TruncateDouble(doubleExponent) == doubleExponent &&
|
||||
base::NumberHelper::TruncateDouble(doubleExponent / 2) + base::HALF == // 2 : half
|
||||
(doubleExponent / 2)) { // 2 : half
|
||||
|
Loading…
Reference in New Issue
Block a user