Skip to content

Commit bcfb526

Browse files
ConstellationMark Lam
authored andcommitted
[JSC] Make PNaN constexpr
https://bugs.webkit.org/show_bug.cgi?id=277677 rdar://133276528 Reviewed by Keith Miller and Justin Michaud. Use C++20 std::bit_cast to make PNaN constexpr. * Source/JavaScriptCore/API/tests/testapi.cpp: (TestAPI::testBigInt): * Source/JavaScriptCore/b3/air/testair.cpp: * Source/JavaScriptCore/runtime/PureNaN.h: (JSC::isImpureNaN): (JSC::purifyNaN): (JSC::pureNaN): Deleted. * Source/JavaScriptCore/wasm/js/JSToWasm.cpp: (JSC::Wasm::marshallJSResult): * Source/WebCore/testing/TypeConversions.h: (WebCore::TypeConversions::testPureNaNUnrestrictedDouble const): Canonical link: https://commits.webkit.org/281891@main
1 parent 0b50ca8 commit bcfb526

5 files changed

Lines changed: 31 additions & 35 deletions

File tree

‎Source/JavaScriptCore/API/tests/testapi.cpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@ void TestAPI::testBigInt()
763763
check(JSValueCompareDouble(context, bigint, number, exception) == kJSRelationConditionEqual, description, ", should kJSRelationConditionEqual to number"_s);
764764
check(JSValueCompareDouble(context, bigint, number + 1, exception) == kJSRelationConditionLessThan, description, ", should kJSRelationConditionLessThan number + 1"_s);
765765
check(JSValueCompareDouble(context, bigint, number - 1, exception) == kJSRelationConditionGreaterThan, description, ", should kJSRelationConditionGreaterThan number - 1"_s);
766-
check(JSValueCompareDouble(context, bigint, JSC::pureNaN(), exception) == kJSRelationConditionUndefined, description, ", should equal to kJSRelationConditionUndefined"_s);
766+
check(JSValueCompareDouble(context, bigint, JSC::PNaN, exception) == kJSRelationConditionUndefined, description, ", should equal to kJSRelationConditionUndefined"_s);
767767
return bigint;
768768
}, description);
769769
}
@@ -787,7 +787,7 @@ void TestAPI::testBigInt()
787787
}
788788

789789
{
790-
double number = JSC::pureNaN();
790+
double number = JSC::PNaN;
791791
const char* description = "checking JSValueMakeBigIntFromNumber with NaN";
792792
checkJSAndAPIMatch(
793793
[&] {

‎Source/JavaScriptCore/b3/air/testair.cpp‎

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1676,7 +1676,7 @@ void testX86VMULSD()
16761676
root->append(MoveDouble, nullptr, Tmp(FPRInfo::argumentFPR2), Tmp(FPRInfo::returnValueFPR));
16771677
root->append(RetDouble, nullptr, Tmp(FPRInfo::returnValueFPR));
16781678

1679-
CHECK(compileAndRun<double>(proc, 2.4, 4.2, pureNaN()) == 2.4 * 4.2);
1679+
CHECK(compileAndRun<double>(proc, 2.4, 4.2, PNaN) == 2.4 * 4.2);
16801680
}
16811681

16821682
void testX86VMULSDDestRex()
@@ -1689,7 +1689,7 @@ void testX86VMULSDDestRex()
16891689
root->append(MoveDouble, nullptr, Tmp(X86Registers::xmm15), Tmp(FPRInfo::returnValueFPR));
16901690
root->append(RetDouble, nullptr, Tmp(FPRInfo::returnValueFPR));
16911691

1692-
CHECK(compileAndRun<double>(proc, 2.4, 4.2, pureNaN()) == 2.4 * 4.2);
1692+
CHECK(compileAndRun<double>(proc, 2.4, 4.2, PNaN) == 2.4 * 4.2);
16931693
}
16941694

16951695
void testX86VMULSDOp1DestRex()
@@ -1703,7 +1703,7 @@ void testX86VMULSDOp1DestRex()
17031703
root->append(MoveDouble, nullptr, Tmp(X86Registers::xmm15), Tmp(FPRInfo::returnValueFPR));
17041704
root->append(RetDouble, nullptr, Tmp(FPRInfo::returnValueFPR));
17051705

1706-
CHECK(compileAndRun<double>(proc, 2.4, 4.2, pureNaN()) == 2.4 * 4.2);
1706+
CHECK(compileAndRun<double>(proc, 2.4, 4.2, PNaN) == 2.4 * 4.2);
17071707
}
17081708

17091709
void testX86VMULSDOp2DestRex()
@@ -1717,7 +1717,7 @@ void testX86VMULSDOp2DestRex()
17171717
root->append(MoveDouble, nullptr, Tmp(X86Registers::xmm15), Tmp(FPRInfo::returnValueFPR));
17181718
root->append(RetDouble, nullptr, Tmp(FPRInfo::returnValueFPR));
17191719

1720-
CHECK(compileAndRun<double>(proc, 2.4, 4.2, pureNaN()) == 2.4 * 4.2);
1720+
CHECK(compileAndRun<double>(proc, 2.4, 4.2, PNaN) == 2.4 * 4.2);
17211721
}
17221722

17231723
void testX86VMULSDOpsDestRex()
@@ -1732,7 +1732,7 @@ void testX86VMULSDOpsDestRex()
17321732
root->append(MoveDouble, nullptr, Tmp(X86Registers::xmm15), Tmp(FPRInfo::returnValueFPR));
17331733
root->append(RetDouble, nullptr, Tmp(FPRInfo::returnValueFPR));
17341734

1735-
CHECK(compileAndRun<double>(proc, 2.4, 4.2, pureNaN()) == 2.4 * 4.2);
1735+
CHECK(compileAndRun<double>(proc, 2.4, 4.2, PNaN) == 2.4 * 4.2);
17361736
}
17371737

17381738
void testX86VMULSDAddr()
@@ -1746,7 +1746,7 @@ void testX86VMULSDAddr()
17461746
root->append(RetDouble, nullptr, Tmp(FPRInfo::returnValueFPR));
17471747

17481748
double secondArg = 4.2;
1749-
CHECK(compileAndRun<double>(proc, 2.4, &secondArg + 2, pureNaN()) == 2.4 * 4.2);
1749+
CHECK(compileAndRun<double>(proc, 2.4, &secondArg + 2, PNaN) == 2.4 * 4.2);
17501750
}
17511751

17521752
void testX86VMULSDAddrOpRexAddr()
@@ -1761,7 +1761,7 @@ void testX86VMULSDAddrOpRexAddr()
17611761
root->append(RetDouble, nullptr, Tmp(FPRInfo::returnValueFPR));
17621762

17631763
double secondArg = 4.2;
1764-
CHECK(compileAndRun<double>(proc, 2.4, &secondArg + 2, pureNaN()) == 2.4 * 4.2);
1764+
CHECK(compileAndRun<double>(proc, 2.4, &secondArg + 2, PNaN) == 2.4 * 4.2);
17651765
}
17661766

17671767
void testX86VMULSDDestRexAddr()
@@ -1775,7 +1775,7 @@ void testX86VMULSDDestRexAddr()
17751775
root->append(RetDouble, nullptr, Tmp(FPRInfo::returnValueFPR));
17761776

17771777
double secondArg = 4.2;
1778-
CHECK(compileAndRun<double>(proc, 2.4, &secondArg - 2, pureNaN()) == 2.4 * 4.2);
1778+
CHECK(compileAndRun<double>(proc, 2.4, &secondArg - 2, PNaN) == 2.4 * 4.2);
17791779
}
17801780

17811781
void testX86VMULSDRegOpDestRexAddr()
@@ -1790,7 +1790,7 @@ void testX86VMULSDRegOpDestRexAddr()
17901790
root->append(RetDouble, nullptr, Tmp(FPRInfo::returnValueFPR));
17911791

17921792
double secondArg = 4.2;
1793-
CHECK(compileAndRun<double>(proc, 2.4, &secondArg, pureNaN()) == 2.4 * 4.2);
1793+
CHECK(compileAndRun<double>(proc, 2.4, &secondArg, PNaN) == 2.4 * 4.2);
17941794
}
17951795

17961796
void testX86VMULSDAddrOpDestRexAddr()
@@ -1805,7 +1805,7 @@ void testX86VMULSDAddrOpDestRexAddr()
18051805
root->append(RetDouble, nullptr, Tmp(FPRInfo::returnValueFPR));
18061806

18071807
double secondArg = 4.2;
1808-
CHECK(compileAndRun<double>(proc, 2.4, &secondArg - 1, pureNaN()) == 2.4 * 4.2);
1808+
CHECK(compileAndRun<double>(proc, 2.4, &secondArg - 1, PNaN) == 2.4 * 4.2);
18091809
}
18101810

18111811
void testX86VMULSDBaseNeedsRex()
@@ -1821,7 +1821,7 @@ void testX86VMULSDBaseNeedsRex()
18211821

18221822
double secondArg = 4.2;
18231823
uint64_t index = 8;
1824-
CHECK(compileAndRun<double>(proc, 2.4, &secondArg - 1, index, pureNaN()) == 2.4 * 4.2);
1824+
CHECK(compileAndRun<double>(proc, 2.4, &secondArg - 1, index, PNaN) == 2.4 * 4.2);
18251825
}
18261826

18271827
void testX86VMULSDIndexNeedsRex()
@@ -1837,7 +1837,7 @@ void testX86VMULSDIndexNeedsRex()
18371837

18381838
double secondArg = 4.2;
18391839
uint64_t index = - 8;
1840-
CHECK(compileAndRun<double>(proc, 2.4, &secondArg + 1, index, pureNaN()) == 2.4 * 4.2);
1840+
CHECK(compileAndRun<double>(proc, 2.4, &secondArg + 1, index, PNaN) == 2.4 * 4.2);
18411841
}
18421842

18431843
void testX86VMULSDBaseIndexNeedRex()
@@ -1854,7 +1854,7 @@ void testX86VMULSDBaseIndexNeedRex()
18541854

18551855
double secondArg = 4.2;
18561856
uint64_t index = 16;
1857-
CHECK(compileAndRun<double>(proc, 2.4, &secondArg - 2, index, pureNaN()) == 2.4 * 4.2);
1857+
CHECK(compileAndRun<double>(proc, 2.4, &secondArg - 2, index, PNaN) == 2.4 * 4.2);
18581858
}
18591859
#endif // #if CPU(X86_64)
18601860

‎Source/JavaScriptCore/runtime/PureNaN.h‎

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#pragma once
2727

28+
#include <bit>
2829
#include <wtf/Assertions.h>
2930
#include <wtf/StdLibExtras.h>
3031

@@ -62,34 +63,29 @@ namespace JSC {
6263
// test. We say that a NaN is "impure" if attempting to tag it would result in a value
6364
// that would look like something other than a double.
6465

65-
// Returns some kind of pure NaN.
66-
inline double pureNaN()
67-
{
68-
// Be sure that we return exactly the kind of NaN that is safe. We engineer the bits
69-
// ourselves to ensure that it's !isImpureNaN(). FWIW, this is what
70-
// numeric_limits<double>::quiet_NaN() returns on Mac/X86_64. But AFAICT there is
71-
// no guarantee that quiet_NaN would return a pureNaN on all platforms. For example,
72-
// the docs appear to imply that quiet_NaN could even return a double with the
73-
// signaling bit set on hardware that doesn't do signaling. That would probably
74-
// never happen, but it's healthy to be paranoid.
75-
return bitwise_cast<double>(0x7ff8000000000000ll);
76-
}
66+
// Some kind of pure NaN.
67+
// Be sure that we define exactly the kind of NaN that is safe. We engineer the bits
68+
// ourselves to ensure that it's !isImpureNaN(). FWIW, this is what
69+
// numeric_limits<double>::quiet_NaN() returns on Mac/X86_64. But AFAICT there is
70+
// no guarantee that quiet_NaN would return a pureNaN on all platforms. For example,
71+
// the docs appear to imply that quiet_NaN could even return a double with the
72+
// signaling bit set on hardware that doesn't do signaling. That would probably
73+
// never happen, but it's healthy to be paranoid.
74+
static constexpr double PNaN { std::bit_cast<double>(0x7ff8000000000000ll) };
7775

78-
#define PNaN (pureNaN())
79-
80-
inline bool isImpureNaN(double value)
76+
inline constexpr bool isImpureNaN(double value)
8177
{
8278
// Tests if the double value would break JSVALUE64 encoding, which is the most
8379
// aggressive kind of encoding that we currently use.
84-
return bitwise_cast<uint64_t>(value) >= 0xfffe000000000000llu;
80+
return std::bit_cast<uint64_t>(value) >= 0xfffe000000000000llu;
8581
}
8682

8783
// If the given value is NaN then return a NaN that is known to be pure.
88-
inline double purifyNaN(double value)
84+
inline constexpr double purifyNaN(double value)
8985
{
9086
if (value != value)
9187
return PNaN;
9288
return value;
93-
}
89+
}
9490

9591
} // namespace JSC

‎Source/JavaScriptCore/wasm/js/JSToWasm.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ void marshallJSResult(CCallHelpers& jit, const TypeDefinition& typeDefinition, c
6060
jit.convertFloatToDouble(src.fpr(), src.fpr());
6161
FALLTHROUGH;
6262
case TypeKind::F64: {
63-
jit.moveTrustedValue(jsNumber(pureNaN()), dst);
63+
jit.moveTrustedValue(jsNumber(PNaN), dst);
6464
auto isNaN = jit.branchIfNaN(src.fpr());
6565
#if USE(JSVALUE64)
6666
jit.boxDouble(src.fpr(), dst, DoNotHaveTagRegisters);

‎Source/WebCore/testing/TypeConversions.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ class TypeConversions : public RefCounted<TypeConversions> {
149149
double testImpureNaNUnrestrictedDouble() const { return bitwise_cast<double>(0xffff000000000000ll); }
150150
double testImpureNaN2UnrestrictedDouble() const { return bitwise_cast<double>(0x7ff8000000000001ll); }
151151
double testQuietNaNUnrestrictedDouble() const { return std::numeric_limits<double>::quiet_NaN(); }
152-
double testPureNaNUnrestrictedDouble() const { return JSC::pureNaN(); }
152+
double testPureNaNUnrestrictedDouble() const { return JSC::PNaN; }
153153

154154
private:
155155
TypeConversions() = default;

0 commit comments

Comments
 (0)