Title: [243277] trunk
- Revision
- 243277
- Author
- [email protected]
- Date
- 2019-03-20 22:41:21 -0700 (Wed, 20 Mar 2019)
Log Message
typeOfDoubleSum is wrong for when NaN can be produced
https://bugs.webkit.org/show_bug.cgi?id=196030
Reviewed by Filip Pizlo.
JSTests:
* stress/double-add-sub-mul-can-produce-nan.js: Added.
(assert):
(noInline.sub):
(noInline):
(assert.mul):
(assert.add):
Source/_javascript_Core:
We were using typeOfDoubleSum(SpeculatedType, SpeculatedType) for add/sub/mul.
It assumed that the only way the resulting type could be NaN is if one of
the inputs were NaN. However, this is wrong. NaN can be produced in at least
these cases:
Infinity - Infinity
Infinity + (-Infinity)
Infinity * 0
* bytecode/SpeculatedType.cpp:
(JSC::typeOfDoubleSumOrDifferenceOrProduct):
(JSC::typeOfDoubleSum):
(JSC::typeOfDoubleDifference):
(JSC::typeOfDoubleProduct):
Modified Paths
Added Paths
Diff
Modified: trunk/JSTests/ChangeLog (243276 => 243277)
--- trunk/JSTests/ChangeLog 2019-03-21 04:38:29 UTC (rev 243276)
+++ trunk/JSTests/ChangeLog 2019-03-21 05:41:21 UTC (rev 243277)
@@ -1,3 +1,17 @@
+2019-03-20 Saam Barati <[email protected]>
+
+ typeOfDoubleSum is wrong for when NaN can be produced
+ https://bugs.webkit.org/show_bug.cgi?id=196030
+
+ Reviewed by Filip Pizlo.
+
+ * stress/double-add-sub-mul-can-produce-nan.js: Added.
+ (assert):
+ (noInline.sub):
+ (noInline):
+ (assert.mul):
+ (assert.add):
+
2019-03-20 Yusuke Suzuki <[email protected]>
Update the test to ensure OutOfMemoryError is thrown as intended
Added: trunk/JSTests/stress/double-add-sub-mul-can-produce-nan.js (0 => 243277)
--- trunk/JSTests/stress/double-add-sub-mul-can-produce-nan.js (rev 0)
+++ trunk/JSTests/stress/double-add-sub-mul-can-produce-nan.js 2019-03-21 05:41:21 UTC (rev 243277)
@@ -0,0 +1,77 @@
+"use strict";
+
+function assert(b) {
+ if (!b)
+ throw new Error;
+}
+noInline(assert);
+
+{
+ function sub(arr, b, c) {
+ let x = b - c;
+ arr[0] = x;
+ }
+ noInline(sub);
+
+
+ for (let i = 0; i < 10000; ++i) {
+ let arr = [];
+ arr.length = 2;
+ arr[1] = 10.5;
+ sub(arr, 10.5, 20.5);
+ assert(0 in arr);
+ }
+
+ let arr = [];
+ arr.length = 2;
+ arr[1] = 10.5;
+ sub(arr, Infinity, Infinity);
+ assert(typeof arr[0] === "number" && isNaN(arr[0]));
+ assert(0 in arr);
+}
+
+{
+ function mul(arr, b, c) {
+ let x = b * c;
+ arr[0] = x;
+ }
+ noInline(mul);
+
+ for (let i = 0; i < 10000; ++i) {
+ let arr = [];
+ arr.length = 2;
+ arr[1] = 10.5;
+ mul(arr, 10.5, 20.5);
+ assert(0 in arr);
+ }
+
+ let arr = [];
+ arr.length = 2;
+ arr[1] = 10.5;
+ mul(arr, Infinity, 0);
+ assert(typeof arr[0] === "number" && isNaN(arr[0]));
+ assert(0 in arr);
+}
+
+{
+ function add(arr, b, c) {
+ let x = b + c;
+ arr[0] = x;
+ }
+ noInline(add);
+
+ for (let i = 0; i < 10000; ++i) {
+ let arr = [];
+ arr.length = 2;
+ arr[1] = 10.5;
+ add(arr, 10.5, 20.5);
+ assert(0 in arr);
+ }
+
+ let arr = [];
+ arr.length = 2;
+ arr[1] = 10.5;
+ add(arr, Infinity, -Infinity);
+ assert(typeof arr[0] === "number" && isNaN(arr[0]));
+ assert(0 in arr);
+}
Modified: trunk/Source/_javascript_Core/ChangeLog (243276 => 243277)
--- trunk/Source/_javascript_Core/ChangeLog 2019-03-21 04:38:29 UTC (rev 243276)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-03-21 05:41:21 UTC (rev 243277)
@@ -1,3 +1,24 @@
+2019-03-20 Saam Barati <[email protected]>
+
+ typeOfDoubleSum is wrong for when NaN can be produced
+ https://bugs.webkit.org/show_bug.cgi?id=196030
+
+ Reviewed by Filip Pizlo.
+
+ We were using typeOfDoubleSum(SpeculatedType, SpeculatedType) for add/sub/mul.
+ It assumed that the only way the resulting type could be NaN is if one of
+ the inputs were NaN. However, this is wrong. NaN can be produced in at least
+ these cases:
+ Infinity - Infinity
+ Infinity + (-Infinity)
+ Infinity * 0
+
+ * bytecode/SpeculatedType.cpp:
+ (JSC::typeOfDoubleSumOrDifferenceOrProduct):
+ (JSC::typeOfDoubleSum):
+ (JSC::typeOfDoubleDifference):
+ (JSC::typeOfDoubleProduct):
+
2019-03-20 Simon Fraser <[email protected]>
Rename ENABLE_ACCELERATED_OVERFLOW_SCROLLING macro to ENABLE_OVERFLOW_SCROLLING_TOUCH
Modified: trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp (243276 => 243277)
--- trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp 2019-03-21 04:38:29 UTC (rev 243276)
+++ trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp 2019-03-21 05:41:21 UTC (rev 243277)
@@ -612,9 +612,18 @@
return !!(a & b);
}
-SpeculatedType typeOfDoubleSum(SpeculatedType a, SpeculatedType b)
+static SpeculatedType typeOfDoubleSumOrDifferenceOrProduct(SpeculatedType a, SpeculatedType b)
{
SpeculatedType result = a | b;
+
+ if (result & SpecNonIntAsDouble) {
+ // NaN can be produced by:
+ // Infinity - Infinity
+ // Infinity + (-Infinity)
+ // Infinity * 0
+ result |= SpecDoublePureNaN;
+ }
+
// Impure NaN could become pure NaN during addition because addition may clear bits.
if (result & SpecDoubleImpureNaN)
result |= SpecDoublePureNaN;
@@ -624,14 +633,19 @@
return result;
}
+SpeculatedType typeOfDoubleSum(SpeculatedType a, SpeculatedType b)
+{
+ return typeOfDoubleSumOrDifferenceOrProduct(a, b);
+}
+
SpeculatedType typeOfDoubleDifference(SpeculatedType a, SpeculatedType b)
{
- return typeOfDoubleSum(a, b);
+ return typeOfDoubleSumOrDifferenceOrProduct(a, b);
}
SpeculatedType typeOfDoubleProduct(SpeculatedType a, SpeculatedType b)
{
- return typeOfDoubleSum(a, b);
+ return typeOfDoubleSumOrDifferenceOrProduct(a, b);
}
static SpeculatedType polluteDouble(SpeculatedType value)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes