Diff
Modified: trunk/JSTests/ChangeLog (260659 => 260660)
--- trunk/JSTests/ChangeLog 2020-04-24 18:42:53 UTC (rev 260659)
+++ trunk/JSTests/ChangeLog 2020-04-24 19:19:23 UTC (rev 260660)
@@ -1,3 +1,65 @@
+2020-04-24 Yusuke Suzuki <[email protected]>
+
+ [JSC] DFG compare should speculate BigInt well
+ https://bugs.webkit.org/show_bug.cgi?id=210892
+
+ Reviewed by Saam Barati.
+
+ * stress/compare-bigint-with-number.js: Added.
+ (shouldBe):
+ (result):
+ (lessThan):
+ (lessThanEqual):
+ (greaterThan):
+ (greaterThanEqual):
+ (equal):
+ * stress/compare-bigint-with-string.js: Added.
+ (shouldBe):
+ (result):
+ (lessThan):
+ (lessThanEqual):
+ (greaterThan):
+ (greaterThanEqual):
+ (equal):
+ * stress/compare-bigint.js: Added.
+ (shouldBe):
+ (result):
+ (lessThan):
+ (lessThanEqual):
+ (greaterThan):
+ (greaterThanEqual):
+ (equal):
+ * stress/compare-bigint32.js: Added.
+ (shouldBe):
+ (result):
+ (lessThan):
+ (lessThanEqual):
+ (greaterThan):
+ (greaterThanEqual):
+ (equal):
+ * stress/compare-heap-bigint.js: Added.
+ (shouldBe):
+ (result):
+ (lessThan):
+ (lessThanEqual):
+ (greaterThan):
+ (greaterThanEqual):
+ (equal):
+ * stress/dfg-ai-fold-bigint.js: Added.
+ (shouldBe):
+ (allAreTrue):
+ (allAreFalse):
+ (lessThan):
+ (lessThanFalse):
+ (lessThanEqual):
+ (lessThanEqualFalse):
+ (greaterThan):
+ (greaterThanFalse):
+ (greaterThanEqual):
+ (greaterThanEqualFalse):
+ (equal):
+ (equalFalse):
+
2020-04-24 Alexey Shvayka <[email protected]>
Proxy.revocable should not have [[Construct]] slot
Added: trunk/JSTests/stress/compare-bigint-with-number.js (0 => 260660)
--- trunk/JSTests/stress/compare-bigint-with-number.js (rev 0)
+++ trunk/JSTests/stress/compare-bigint-with-number.js 2020-04-24 19:19:23 UTC (rev 260660)
@@ -0,0 +1,280 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+const Greater = 0;
+const Less = 1;
+const Equal = 2;
+const Undefined = 3;
+
+function result(func, data)
+{
+ if (data ="" Undefined)
+ return false;
+ if (func === lessThan)
+ return data ="" Less;
+ if (func === lessThanEqual)
+ return data ="" Less || data ="" Equal;
+ if (func === greaterThan)
+ return data ="" Greater;
+ if (func === greaterThanEqual)
+ return data ="" Greater || data ="" Equal;
+ if (func === equal)
+ return data ="" Equal;
+ return false;
+}
+
+var list = [
+ [createHeapBigInt(1n), 2, Less],
+ [createHeapBigInt(1n), 1, Equal],
+ [createHeapBigInt(1n), 0, Greater],
+ [createHeapBigInt(1n), -1, Greater],
+ [createHeapBigInt(1n), -2, Greater],
+ [createHeapBigInt(0n), 2, Less],
+ [createHeapBigInt(0n), 1, Less],
+ [createHeapBigInt(0n), 0, Equal],
+ [createHeapBigInt(0n), -1, Greater],
+ [createHeapBigInt(0n), -2, Greater],
+ [createHeapBigInt(-1n), 2, Less],
+ [createHeapBigInt(-1n), 1, Less],
+ [createHeapBigInt(-1n), 0, Less],
+ [createHeapBigInt(-1n), -1, Equal],
+ [createHeapBigInt(-1n), -2, Greater],
+
+ [1, createHeapBigInt(2n), Less],
+ [1, createHeapBigInt(1n), Equal],
+ [1, createHeapBigInt(0n), Greater],
+ [1, createHeapBigInt(-1n), Greater],
+ [1, createHeapBigInt(-2n), Greater],
+ [0, createHeapBigInt(2n), Less],
+ [0, createHeapBigInt(1n), Less],
+ [0, createHeapBigInt(0n), Equal],
+ [0, createHeapBigInt(-1n), Greater],
+ [0, createHeapBigInt(-2n), Greater],
+ [-1, createHeapBigInt(2n), Less],
+ [-1, createHeapBigInt(1n), Less],
+ [-1, createHeapBigInt(0n), Less],
+ [-1, createHeapBigInt(-1n), Equal],
+ [-1, createHeapBigInt(-2n), Greater],
+
+ [1, 2n, Less],
+ [1, 1n, Equal],
+ [1, 0n, Greater],
+ [1, -1n, Greater],
+ [1, -2n, Greater],
+ [0, 2n, Less],
+ [0, 1n, Less],
+ [0, 0n, Equal],
+ [0, -1n, Greater],
+ [0, -2n, Greater],
+ [-1, 2n, Less],
+ [-1, 1n, Less],
+ [-1, 0n, Less],
+ [-1, -1n, Equal],
+ [-1, -2n, Greater],
+
+ [1n, 2, Less],
+ [1n, 1, Equal],
+ [1n, 0, Greater],
+ [1n, -1, Greater],
+ [1n, -2, Greater],
+ [0n, 2, Less],
+ [0n, 1, Less],
+ [0n, 0, Equal],
+ [0n, -1, Greater],
+ [0n, -2, Greater],
+ [-1n, 2, Less],
+ [-1n, 1, Less],
+ [-1n, 0, Less],
+ [-1n, -1, Equal],
+ [-1n, -2, Greater],
+
+ [createHeapBigInt(1000000000000000000000000n), 2, Greater],
+ [createHeapBigInt(1000000000000000000000000n), 1, Greater],
+ [createHeapBigInt(1000000000000000000000000n), 0, Greater],
+ [createHeapBigInt(1000000000000000000000000n), -1, Greater],
+ [createHeapBigInt(1000000000000000000000000n), -2, Greater],
+ [createHeapBigInt(-1000000000000000000000000n), 2, Less],
+ [createHeapBigInt(-1000000000000000000000000n), 1, Less],
+ [createHeapBigInt(-1000000000000000000000000n), 0, Less],
+ [createHeapBigInt(-1000000000000000000000000n), -1, Less],
+ [createHeapBigInt(-1000000000000000000000000n), -2, Less],
+
+ [2, createHeapBigInt(1000000000000000000000000n), Less],
+ [1, createHeapBigInt(1000000000000000000000000n), Less],
+ [0, createHeapBigInt(1000000000000000000000000n), Less],
+ [-1, createHeapBigInt(1000000000000000000000000n), Less],
+ [-2, createHeapBigInt(1000000000000000000000000n), Less],
+ [2, createHeapBigInt(-1000000000000000000000000n), Greater],
+ [1, createHeapBigInt(-1000000000000000000000000n), Greater],
+ [0, createHeapBigInt(-1000000000000000000000000n), Greater],
+ [-1, createHeapBigInt(-1000000000000000000000000n), Greater],
+ [-2, createHeapBigInt(-1000000000000000000000000n), Greater],
+
+ [1.5, 2n, Less],
+ [1.0, 1n, Equal],
+ [1.5, 0n, Greater],
+ [1.5, -1n, Greater],
+ [1.5, -2n, Greater],
+ [0.5, 2n, Less],
+ [0.5, 1n, Less],
+ [-0.0, 0n, Equal],
+ [0.0, 0n, Equal],
+ [0.5, -1n, Greater],
+ [0.5, -2n, Greater],
+ [-1.5, 2n, Less],
+ [-1.5, 1n, Less],
+ [-1.5, 0n, Less],
+ [-1.0, -1n, Equal],
+ [-1.5, -2n, Greater],
+
+ [1n, 2.5, Less],
+ [1n, 1.0, Equal],
+ [1n, 0.5, Greater],
+ [1n, -1.5, Greater],
+ [1n, -2.5, Greater],
+ [0n, 2.5, Less],
+ [0n, 1.0, Less],
+ [0n, 0.0, Equal],
+ [0n, -0.0, Equal],
+ [0n, -1.5, Greater],
+ [0n, -2.5, Greater],
+ [-1n, 2.5, Less],
+ [-1n, 1.0, Less],
+ [-1n, 0.5, Less],
+ [-1n, -1.0, Equal],
+ [-1n, -2.5, Greater],
+
+ [createHeapBigInt(1n), 2.5, Less],
+ [createHeapBigInt(1n), 1.0, Equal],
+ [createHeapBigInt(1n), 0.5, Greater],
+ [createHeapBigInt(1n), -1.5, Greater],
+ [createHeapBigInt(1n), -2.5, Greater],
+ [createHeapBigInt(0n), 2.5, Less],
+ [createHeapBigInt(0n), 1.5, Less],
+ [createHeapBigInt(0n), 0.0, Equal],
+ [createHeapBigInt(0n), -0.0, Equal],
+ [createHeapBigInt(0n), -1.5, Greater],
+ [createHeapBigInt(0n), -2.5, Greater],
+ [createHeapBigInt(-1n), 2.5, Less],
+ [createHeapBigInt(-1n), 1.5, Less],
+ [createHeapBigInt(-1n), 0.5, Less],
+ [createHeapBigInt(-1n), -1.0, Equal],
+ [createHeapBigInt(-1n), -2.5, Greater],
+
+ [1.5, createHeapBigInt(2n), Less],
+ [1.0, createHeapBigInt(1n), Equal],
+ [1.5, createHeapBigInt(0n), Greater],
+ [1.5, createHeapBigInt(-1n), Greater],
+ [1.5, createHeapBigInt(-2n), Greater],
+ [0.5, createHeapBigInt(2n), Less],
+ [0.5, createHeapBigInt(1n), Less],
+ [0.0, createHeapBigInt(0n), Equal],
+ [-0.0, createHeapBigInt(0n), Equal],
+ [0.5, createHeapBigInt(-1n), Greater],
+ [0.5, createHeapBigInt(-2n), Greater],
+ [-1.5, createHeapBigInt(2n), Less],
+ [-1.5, createHeapBigInt(1n), Less],
+ [-1.5, createHeapBigInt(0n), Less],
+ [-1.0, createHeapBigInt(-1n), Equal],
+ [-1.5, createHeapBigInt(-2n), Greater],
+
+ [1n, NaN, Undefined],
+ [0n, NaN, Undefined],
+ [-1n, NaN, Undefined],
+
+ [NaN, 1n, Undefined],
+ [NaN, 0n, Undefined],
+ [NaN, -1n, Undefined],
+
+ [createHeapBigInt(1n), NaN, Undefined],
+ [createHeapBigInt(0n), NaN, Undefined],
+ [createHeapBigInt(-1n), NaN, Undefined],
+
+ [NaN, createHeapBigInt(1n), Undefined],
+ [NaN, createHeapBigInt(0n), Undefined],
+ [NaN, createHeapBigInt(-1n), Undefined],
+
+ [1n, Infinity, Less],
+ [0n, Infinity, Less],
+ [-1n, Infinity, Less],
+
+ [Infinity, 1n, Greater],
+ [Infinity, 0n, Greater],
+ [Infinity, -1n, Greater],
+
+ [createHeapBigInt(1n), Infinity, Less],
+ [createHeapBigInt(0n), Infinity, Less],
+ [createHeapBigInt(-1n), Infinity, Less],
+
+ [Infinity, createHeapBigInt(1n), Greater],
+ [Infinity, createHeapBigInt(0n), Greater],
+ [Infinity, createHeapBigInt(-1n), Greater],
+
+ [1n, -Infinity, Greater],
+ [0n, -Infinity, Greater],
+ [-1n, -Infinity, Greater],
+
+ [-Infinity, 1n, Less],
+ [-Infinity, 0n, Less],
+ [-Infinity, -1n, Less],
+
+ [createHeapBigInt(1n), -Infinity, Greater],
+ [createHeapBigInt(0n), -Infinity, Greater],
+ [createHeapBigInt(-1n), -Infinity, Greater],
+
+ [-Infinity, createHeapBigInt(1n), Less],
+ [-Infinity, createHeapBigInt(0n), Less],
+ [-Infinity, createHeapBigInt(-1n), Less],
+
+ [createHeapBigInt(1000000000000000000000000n), Infinity, Less],
+ [Infinity, createHeapBigInt(1000000000000000000000000n), Greater],
+ [createHeapBigInt(1000000000000000000000000n), -Infinity, Greater],
+ [-Infinity, createHeapBigInt(1000000000000000000000000n), Less],
+
+ [createHeapBigInt(-1000000000000000000000000n), Infinity, Less],
+ [Infinity, createHeapBigInt(-1000000000000000000000000n), Greater],
+ [createHeapBigInt(-1000000000000000000000000n), -Infinity, Greater],
+ [-Infinity, createHeapBigInt(-1000000000000000000000000n), Less],
+];
+
+function lessThan(a, b)
+{
+ return a < b;
+}
+noInline(lessThan);
+
+function lessThanEqual(a, b)
+{
+ return a <= b;
+}
+noInline(lessThanEqual);
+
+function greaterThan(a, b)
+{
+ return a > b;
+}
+noInline(greaterThan);
+
+function greaterThanEqual(a, b)
+{
+ return a >= b;
+}
+noInline(greaterThanEqual);
+
+function equal(a, b)
+{
+ return a == b;
+}
+noInline(equal);
+
+for (var i = 0; i < 1e3; ++i) {
+ for (let [a, b, res] of list) {
+ shouldBe(lessThan(a, b), result(lessThan, res));
+ shouldBe(lessThanEqual(a, b), result(lessThanEqual, res));
+ shouldBe(greaterThan(a, b), result(greaterThan, res));
+ shouldBe(greaterThanEqual(a, b), result(greaterThanEqual, res));
+ shouldBe(equal(a, b), result(equal, res));
+ }
+}
Added: trunk/JSTests/stress/compare-bigint-with-string.js (0 => 260660)
--- trunk/JSTests/stress/compare-bigint-with-string.js (rev 0)
+++ trunk/JSTests/stress/compare-bigint-with-string.js 2020-04-24 19:19:23 UTC (rev 260660)
@@ -0,0 +1,236 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+const Greater = 0;
+const Less = 1;
+const Equal = 2;
+const Undefined = 3;
+
+function result(func, data)
+{
+ if (data ="" Undefined)
+ return false;
+ if (func === lessThan)
+ return data ="" Less;
+ if (func === lessThanEqual)
+ return data ="" Less || data ="" Equal;
+ if (func === greaterThan)
+ return data ="" Greater;
+ if (func === greaterThanEqual)
+ return data ="" Greater || data ="" Equal;
+ if (func === equal)
+ return data ="" Equal;
+ return false;
+}
+
+var list = [
+ [createHeapBigInt(1n), "2", Less],
+ [createHeapBigInt(1n), "1", Equal],
+ [createHeapBigInt(1n), "0", Greater],
+ [createHeapBigInt(1n), "-1", Greater],
+ [createHeapBigInt(1n), "-2", Greater],
+ [createHeapBigInt(0n), "2", Less],
+ [createHeapBigInt(0n), "1", Less],
+ [createHeapBigInt(0n), "0", Equal],
+ [createHeapBigInt(0n), "-1", Greater],
+ [createHeapBigInt(0n), "-2", Greater],
+ [createHeapBigInt(-1n), "2", Less],
+ [createHeapBigInt(-1n), "1", Less],
+ [createHeapBigInt(-1n), "0", Less],
+ [createHeapBigInt(-1n), "-1", Equal],
+ [createHeapBigInt(-1n), "-2", Greater],
+
+ ["1", createHeapBigInt(2n), Less],
+ ["1", createHeapBigInt(1n), Equal],
+ ["1", createHeapBigInt(0n), Greater],
+ ["1", createHeapBigInt(-1n), Greater],
+ ["1", createHeapBigInt(-2n), Greater],
+ ["0", createHeapBigInt(2n), Less],
+ ["0", createHeapBigInt(1n), Less],
+ ["0", createHeapBigInt(0n), Equal],
+ ["0", createHeapBigInt(-1n), Greater],
+ ["0", createHeapBigInt(-2n), Greater],
+ ["-1", createHeapBigInt(2n), Less],
+ ["-1", createHeapBigInt(1n), Less],
+ ["-1", createHeapBigInt(0n), Less],
+ ["-1", createHeapBigInt(-1n), Equal],
+ ["-1", createHeapBigInt(-2n), Greater],
+
+ ["1", 2n, Less],
+ ["1", 1n, Equal],
+ ["1", 0n, Greater],
+ ["1", -1n, Greater],
+ ["1", -2n, Greater],
+ ["0", 2n, Less],
+ ["0", 1n, Less],
+ ["0", 0n, Equal],
+ ["0", -1n, Greater],
+ ["0", -2n, Greater],
+ ["-1", 2n, Less],
+ ["-1", 1n, Less],
+ ["-1", 0n, Less],
+ ["-1", -1n, Equal],
+ ["-1", -2n, Greater],
+
+ [1n, "2", Less],
+ [1n, "1", Equal],
+ [1n, "0", Greater],
+ [1n, "-1", Greater],
+ [1n, "-2", Greater],
+ [0n, "2", Less],
+ [0n, "1", Less],
+ [0n, "0", Equal],
+ [0n, "-1", Greater],
+ [0n, "-2", Greater],
+ [-1n, "2", Less],
+ [-1n, "1", Less],
+ [-1n, "0", Less],
+ [-1n, "-1", Equal],
+ [-1n, "-2", Greater],
+
+ [createHeapBigInt(1000000000000000000000000n), "2", Greater],
+ [createHeapBigInt(1000000000000000000000000n), "1", Greater],
+ [createHeapBigInt(1000000000000000000000000n), "0", Greater],
+ [createHeapBigInt(1000000000000000000000000n), "-1", Greater],
+ [createHeapBigInt(1000000000000000000000000n), "-2", Greater],
+ [createHeapBigInt(-1000000000000000000000000n), "2", Less],
+ [createHeapBigInt(-1000000000000000000000000n), "1", Less],
+ [createHeapBigInt(-1000000000000000000000000n), "0", Less],
+ [createHeapBigInt(-1000000000000000000000000n), "-1", Less],
+ [createHeapBigInt(-1000000000000000000000000n), "-2", Less],
+
+ ["2", createHeapBigInt(1000000000000000000000000n), Less],
+ ["1", createHeapBigInt(1000000000000000000000000n), Less],
+ ["0", createHeapBigInt(1000000000000000000000000n), Less],
+ ["-1", createHeapBigInt(1000000000000000000000000n), Less],
+ ["-2", createHeapBigInt(1000000000000000000000000n), Less],
+ ["2", createHeapBigInt(-1000000000000000000000000n), Greater],
+ ["1", createHeapBigInt(-1000000000000000000000000n), Greater],
+ ["0", createHeapBigInt(-1000000000000000000000000n), Greater],
+ ["-1", createHeapBigInt(-1000000000000000000000000n), Greater],
+ ["-2", createHeapBigInt(-1000000000000000000000000n), Greater],
+
+ ["1.5", 2n, Undefined],
+ ["1.0", 1n, Undefined],
+ ["1.5", 0n, Undefined],
+ ["1.5", -1n, Undefined],
+ ["1.5", -2n, Undefined],
+ ["0.5", 2n, Undefined],
+ ["0.5", 1n, Undefined],
+ ["-0.0", 0n, Undefined],
+ ["0.0", 0n, Undefined],
+ ["0.5", -1n, Undefined],
+ ["0.5", -2n, Undefined],
+ ["-1.5", 2n, Undefined],
+ ["-1.5", 1n, Undefined],
+ ["-1.5", 0n, Undefined],
+ ["-1.0", -1n, Undefined],
+ ["-1.5", -2n, Undefined],
+
+ [1n, "2.5", Undefined],
+ [1n, "1.0", Undefined],
+ [1n, "0.5", Undefined],
+ [1n, "-1.5", Undefined],
+ [1n, "-2.5", Undefined],
+ [0n, "2.5", Undefined],
+ [0n, "1.0", Undefined],
+ [0n, "0.0", Undefined],
+ [0n, "-0.0", Undefined],
+ [0n, "-1.5", Undefined],
+ [0n, "-2.5", Undefined],
+ [-1n, "2.5", Undefined],
+ [-1n, "1.0", Undefined],
+ [-1n, "0.5", Undefined],
+ [-1n, "-1.0", Undefined],
+ [-1n, "-2.5", Undefined],
+
+ [createHeapBigInt(1n), "2.5", Undefined],
+ [createHeapBigInt(1n), "1.0", Undefined],
+ [createHeapBigInt(1n), "0.5", Undefined],
+ [createHeapBigInt(1n), "-1.5", Undefined],
+ [createHeapBigInt(1n), "-2.5", Undefined],
+ [createHeapBigInt(0n), "2.5", Undefined],
+ [createHeapBigInt(0n), "1.5", Undefined],
+ [createHeapBigInt(0n), "0.0", Undefined],
+ [createHeapBigInt(0n), "-0.0", Undefined],
+ [createHeapBigInt(0n), "-1.5", Undefined],
+ [createHeapBigInt(0n), "-2.5", Undefined],
+ [createHeapBigInt(-1n), "2.5", Undefined],
+ [createHeapBigInt(-1n), "1.5", Undefined],
+ [createHeapBigInt(-1n), "0.5", Undefined],
+ [createHeapBigInt(-1n), "-1.0", Undefined],
+ [createHeapBigInt(-1n), "-2.5", Undefined],
+
+ ["1.5", createHeapBigInt(2n), Undefined],
+ ["1.0", createHeapBigInt(1n), Undefined],
+ ["1.5", createHeapBigInt(0n), Undefined],
+ ["1.5", createHeapBigInt(-1n), Undefined],
+ ["1.5", createHeapBigInt(-2n), Undefined],
+ ["0.5", createHeapBigInt(2n), Undefined],
+ ["0.5", createHeapBigInt(1n), Undefined],
+ ["0.0", createHeapBigInt(0n), Undefined],
+ ["-0.0", createHeapBigInt(0n), Undefined],
+ ["0.5", createHeapBigInt(-1n), Undefined],
+ ["0.5", createHeapBigInt(-2n), Undefined],
+ ["-1.5", createHeapBigInt(2n), Undefined],
+ ["-1.5", createHeapBigInt(1n), Undefined],
+ ["-1.5", createHeapBigInt(0n), Undefined],
+ ["-1.0", createHeapBigInt(-1n), Undefined],
+ ["-1.5", createHeapBigInt(-2n), Undefined],
+
+ [createHeapBigInt(1000000000000000000000000n), "100000000000000000000000000000000000", Less],
+ ["100000000000000000000000000000000000", createHeapBigInt(1000000000000000000000000n), Greater],
+ [createHeapBigInt(1000000000000000000000000n), "-100000000000000000000000000000000000", Greater],
+ ["-100000000000000000000000000000000000", createHeapBigInt(1000000000000000000000000n), Less],
+ [createHeapBigInt(1000000000000000000000000n), "1000000000000000000000000", Equal],
+ ["1000000000000000000000000", createHeapBigInt(1000000000000000000000000n), Equal],
+ [createHeapBigInt(-1000000000000000000000000n), "-1000000000000000000000000", Equal],
+ ["-1000000000000000000000000", createHeapBigInt(-1000000000000000000000000n), Equal],
+
+ [20n, "100000000000000000000000000000000000", Less],
+ ["100000000000000000000000000000000000", 20n, Greater],
+ [20n, "-100000000000000000000000000000000000", Greater],
+ ["-100000000000000000000000000000000000", 20n, Less],
+];
+
+function lessThan(a, b)
+{
+ return a < b;
+}
+noInline(lessThan);
+
+function lessThanEqual(a, b)
+{
+ return a <= b;
+}
+noInline(lessThanEqual);
+
+function greaterThan(a, b)
+{
+ return a > b;
+}
+noInline(greaterThan);
+
+function greaterThanEqual(a, b)
+{
+ return a >= b;
+}
+noInline(greaterThanEqual);
+
+function equal(a, b)
+{
+ return a == b;
+}
+noInline(equal);
+
+for (var i = 0; i < 1e3; ++i) {
+ for (let [a, b, res] of list) {
+ shouldBe(lessThan(a, b), result(lessThan, res));
+ shouldBe(lessThanEqual(a, b), result(lessThanEqual, res));
+ shouldBe(greaterThan(a, b), result(greaterThan, res));
+ shouldBe(greaterThanEqual(a, b), result(greaterThanEqual, res));
+ shouldBe(equal(a, b), result(equal, res));
+ }
+}
Added: trunk/JSTests/stress/compare-bigint.js (0 => 260660)
--- trunk/JSTests/stress/compare-bigint.js (rev 0)
+++ trunk/JSTests/stress/compare-bigint.js 2020-04-24 19:19:23 UTC (rev 260660)
@@ -0,0 +1,151 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+const Greater = 0;
+const Less = 1;
+const Equal = 2;
+
+function result(func, data)
+{
+ if (func === lessThan)
+ return data ="" Less;
+ if (func === lessThanEqual)
+ return data ="" Less || data ="" Equal;
+ if (func === greaterThan)
+ return data ="" Greater;
+ if (func === greaterThanEqual)
+ return data ="" Greater || data ="" Equal;
+ if (func === equal)
+ return data ="" Equal;
+ return false;
+}
+
+var list = [
+ [createHeapBigInt(1n), 2n, Less],
+ [createHeapBigInt(1n), 1n, Equal],
+ [createHeapBigInt(1n), 0n, Greater],
+ [createHeapBigInt(1n), -1n, Greater],
+ [createHeapBigInt(1n), -2n, Greater],
+ [createHeapBigInt(0n), 2n, Less],
+ [createHeapBigInt(0n), 1n, Less],
+ [createHeapBigInt(0n), 0n, Equal],
+ [createHeapBigInt(0n), -1n, Greater],
+ [createHeapBigInt(0n), -2n, Greater],
+ [createHeapBigInt(-1n), 2n, Less],
+ [createHeapBigInt(-1n), 1n, Less],
+ [createHeapBigInt(-1n), 0n, Less],
+ [createHeapBigInt(-1n), -1n, Equal],
+ [createHeapBigInt(-1n), -2n, Greater],
+
+ [1n, createHeapBigInt(2n), Less],
+ [1n, createHeapBigInt(1n), Equal],
+ [1n, createHeapBigInt(0n), Greater],
+ [1n, createHeapBigInt(-1n), Greater],
+ [1n, createHeapBigInt(-2n), Greater],
+ [0n, createHeapBigInt(2n), Less],
+ [0n, createHeapBigInt(1n), Less],
+ [0n, createHeapBigInt(0n), Equal],
+ [0n, createHeapBigInt(-1n), Greater],
+ [0n, createHeapBigInt(-2n), Greater],
+ [-1n, createHeapBigInt(2n), Less],
+ [-1n, createHeapBigInt(1n), Less],
+ [-1n, createHeapBigInt(0n), Less],
+ [-1n, createHeapBigInt(-1n), Equal],
+ [-1n, createHeapBigInt(-2n), Greater],
+
+ [1n, 2n, Less],
+ [1n, 1n, Equal],
+ [1n, 0n, Greater],
+ [1n, -1n, Greater],
+ [1n, -2n, Greater],
+ [0n, 2n, Less],
+ [0n, 1n, Less],
+ [0n, 0n, Equal],
+ [0n, -1n, Greater],
+ [0n, -2n, Greater],
+ [-1n, 2n, Less],
+ [-1n, 1n, Less],
+ [-1n, 0n, Less],
+ [-1n, -1n, Equal],
+ [-1n, -2n, Greater],
+
+ [createHeapBigInt(1n), createHeapBigInt(2n), Less],
+ [createHeapBigInt(1n), createHeapBigInt(1n), Equal],
+ [createHeapBigInt(1n), createHeapBigInt(0n), Greater],
+ [createHeapBigInt(1n), createHeapBigInt(-1n), Greater],
+ [createHeapBigInt(1n), createHeapBigInt(-2n), Greater],
+ [createHeapBigInt(0n), createHeapBigInt(2n), Less],
+ [createHeapBigInt(0n), createHeapBigInt(1n), Less],
+ [createHeapBigInt(0n), createHeapBigInt(0n), Equal],
+ [createHeapBigInt(0n), createHeapBigInt(-1n), Greater],
+ [createHeapBigInt(0n), createHeapBigInt(-2n), Greater],
+ [createHeapBigInt(-1n), createHeapBigInt(2n), Less],
+ [createHeapBigInt(-1n), createHeapBigInt(1n), Less],
+ [createHeapBigInt(-1n), createHeapBigInt(0n), Less],
+ [createHeapBigInt(-1n), createHeapBigInt(-1n), Equal],
+ [createHeapBigInt(-1n), createHeapBigInt(-2n), Greater],
+
+ [createHeapBigInt(1000000000000000000000000n), 2n, Greater],
+ [createHeapBigInt(1000000000000000000000000n), 1n, Greater],
+ [createHeapBigInt(1000000000000000000000000n), 0n, Greater],
+ [createHeapBigInt(1000000000000000000000000n), -1n, Greater],
+ [createHeapBigInt(1000000000000000000000000n), -2n, Greater],
+ [createHeapBigInt(-1000000000000000000000000n), 2n, Less],
+ [createHeapBigInt(-1000000000000000000000000n), 1n, Less],
+ [createHeapBigInt(-1000000000000000000000000n), 0n, Less],
+ [createHeapBigInt(-1000000000000000000000000n), -1n, Less],
+ [createHeapBigInt(-1000000000000000000000000n), -2n, Less],
+
+ [2n, createHeapBigInt(1000000000000000000000000n), Less],
+ [1n, createHeapBigInt(1000000000000000000000000n), Less],
+ [0n, createHeapBigInt(1000000000000000000000000n), Less],
+ [-1n, createHeapBigInt(1000000000000000000000000n), Less],
+ [-2n, createHeapBigInt(1000000000000000000000000n), Less],
+ [2n, createHeapBigInt(-1000000000000000000000000n), Greater],
+ [1n, createHeapBigInt(-1000000000000000000000000n), Greater],
+ [0n, createHeapBigInt(-1000000000000000000000000n), Greater],
+ [-1n, createHeapBigInt(-1000000000000000000000000n), Greater],
+ [-2n, createHeapBigInt(-1000000000000000000000000n), Greater],
+];
+
+function lessThan(a, b)
+{
+ return a < b;
+}
+noInline(lessThan);
+
+function lessThanEqual(a, b)
+{
+ return a <= b;
+}
+noInline(lessThanEqual);
+
+function greaterThan(a, b)
+{
+ return a > b;
+}
+noInline(greaterThan);
+
+function greaterThanEqual(a, b)
+{
+ return a >= b;
+}
+noInline(greaterThanEqual);
+
+function equal(a, b)
+{
+ return a == b;
+}
+noInline(equal);
+
+for (var i = 0; i < 1e3; ++i) {
+ for (let [a, b, res] of list) {
+ shouldBe(lessThan(a, b), result(lessThan, res));
+ shouldBe(lessThanEqual(a, b), result(lessThanEqual, res));
+ shouldBe(greaterThan(a, b), result(greaterThan, res));
+ shouldBe(greaterThanEqual(a, b), result(greaterThanEqual, res));
+ shouldBe(equal(a, b), result(equal, res));
+ }
+}
Added: trunk/JSTests/stress/compare-bigint32.js (0 => 260660)
--- trunk/JSTests/stress/compare-bigint32.js (rev 0)
+++ trunk/JSTests/stress/compare-bigint32.js 2020-04-24 19:19:23 UTC (rev 260660)
@@ -0,0 +1,81 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+const Greater = 0;
+const Less = 1;
+const Equal = 2;
+
+function result(func, data)
+{
+ if (func === lessThan)
+ return data ="" Less;
+ if (func === lessThanEqual)
+ return data ="" Less || data ="" Equal;
+ if (func === greaterThan)
+ return data ="" Greater;
+ if (func === greaterThanEqual)
+ return data ="" Greater || data ="" Equal;
+ if (func === equal)
+ return data ="" Equal;
+ return false;
+}
+
+var list = [
+ [1n, 2n, Less],
+ [1n, 1n, Equal],
+ [1n, 0n, Greater],
+ [1n, -1n, Greater],
+ [1n, -2n, Greater],
+ [0n, 2n, Less],
+ [0n, 1n, Less],
+ [0n, 0n, Equal],
+ [0n, -1n, Greater],
+ [0n, -2n, Greater],
+ [-1n, 2n, Less],
+ [-1n, 1n, Less],
+ [-1n, 0n, Less],
+ [-1n, -1n, Equal],
+ [-1n, -2n, Greater],
+];
+
+function lessThan(a, b)
+{
+ return a < b;
+}
+noInline(lessThan);
+
+function lessThanEqual(a, b)
+{
+ return a <= b;
+}
+noInline(lessThanEqual);
+
+function greaterThan(a, b)
+{
+ return a > b;
+}
+noInline(greaterThan);
+
+function greaterThanEqual(a, b)
+{
+ return a >= b;
+}
+noInline(greaterThanEqual);
+
+function equal(a, b)
+{
+ return a == b;
+}
+noInline(equal);
+
+for (var i = 0; i < 1e3; ++i) {
+ for (let [a, b, res] of list) {
+ shouldBe(lessThan(a, b), result(lessThan, res));
+ shouldBe(lessThanEqual(a, b), result(lessThanEqual, res));
+ shouldBe(greaterThan(a, b), result(greaterThan, res));
+ shouldBe(greaterThanEqual(a, b), result(greaterThanEqual, res));
+ shouldBe(equal(a, b), result(equal, res));
+ }
+}
Added: trunk/JSTests/stress/compare-heap-bigint.js (0 => 260660)
--- trunk/JSTests/stress/compare-heap-bigint.js (rev 0)
+++ trunk/JSTests/stress/compare-heap-bigint.js 2020-04-24 19:19:23 UTC (rev 260660)
@@ -0,0 +1,103 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+const Greater = 0;
+const Less = 1;
+const Equal = 2;
+
+function result(func, data)
+{
+ if (func === lessThan)
+ return data ="" Less;
+ if (func === lessThanEqual)
+ return data ="" Less || data ="" Equal;
+ if (func === greaterThan)
+ return data ="" Greater;
+ if (func === greaterThanEqual)
+ return data ="" Greater || data ="" Equal;
+ if (func === equal)
+ return data ="" Equal;
+ return false;
+}
+
+var list = [
+ [createHeapBigInt(1n), createHeapBigInt(2n), Less],
+ [createHeapBigInt(1n), createHeapBigInt(1n), Equal],
+ [createHeapBigInt(1n), createHeapBigInt(0n), Greater],
+ [createHeapBigInt(1n), createHeapBigInt(-1n), Greater],
+ [createHeapBigInt(1n), createHeapBigInt(-2n), Greater],
+ [createHeapBigInt(0n), createHeapBigInt(2n), Less],
+ [createHeapBigInt(0n), createHeapBigInt(1n), Less],
+ [createHeapBigInt(0n), createHeapBigInt(0n), Equal],
+ [createHeapBigInt(0n), createHeapBigInt(-1n), Greater],
+ [createHeapBigInt(0n), createHeapBigInt(-2n), Greater],
+ [createHeapBigInt(-1n), createHeapBigInt(2n), Less],
+ [createHeapBigInt(-1n), createHeapBigInt(1n), Less],
+ [createHeapBigInt(-1n), createHeapBigInt(0n), Less],
+ [createHeapBigInt(-1n), createHeapBigInt(-1n), Equal],
+ [createHeapBigInt(-1n), createHeapBigInt(-2n), Greater],
+
+ [createHeapBigInt(1000000000000000000000000n), createHeapBigInt(2n), Greater],
+ [createHeapBigInt(1000000000000000000000000n), createHeapBigInt(1n), Greater],
+ [createHeapBigInt(1000000000000000000000000n), createHeapBigInt(0n), Greater],
+ [createHeapBigInt(1000000000000000000000000n), createHeapBigInt(-1n), Greater],
+ [createHeapBigInt(1000000000000000000000000n), createHeapBigInt(-2n), Greater],
+ [createHeapBigInt(-1000000000000000000000000n), createHeapBigInt(2n), Less],
+ [createHeapBigInt(-1000000000000000000000000n), createHeapBigInt(1n), Less],
+ [createHeapBigInt(-1000000000000000000000000n), createHeapBigInt(0n), Less],
+ [createHeapBigInt(-1000000000000000000000000n), createHeapBigInt(-1n), Less],
+ [createHeapBigInt(-1000000000000000000000000n), createHeapBigInt(-2n), Less],
+
+ [createHeapBigInt(1000000000000000000000000n), createHeapBigInt(1000000000000000000000002n), Less],
+ [createHeapBigInt(1000000000000000000000001n), createHeapBigInt(1000000000000000000000000n), Greater],
+ [createHeapBigInt(1000000000000000000000000n), createHeapBigInt(1000000000000000000000000n), Equal],
+ [createHeapBigInt(-1000000000000000000000000n), createHeapBigInt(-1000000000000000000000000n), Equal],
+ [createHeapBigInt(1000000000000000000000000n), createHeapBigInt(-1000000000000000000000001n), Greater],
+ [createHeapBigInt(-1000000000000000000000000n), createHeapBigInt(1000000000000000000000002n), Less],
+ [createHeapBigInt(-1000000000000000000000000n), createHeapBigInt(1000000000000000000000001n), Less],
+ [createHeapBigInt(-1000000000000000000000000n), createHeapBigInt(1000000000000000000000000n), Less],
+ [createHeapBigInt(-1000000000000000000000000n), createHeapBigInt(-1000000000000000000000001n), Greater],
+ [createHeapBigInt(-1000000000000000000000000n), createHeapBigInt(-1000000000000000000000002n), Greater],
+];
+
+function lessThan(a, b)
+{
+ return a < b;
+}
+noInline(lessThan);
+
+function lessThanEqual(a, b)
+{
+ return a <= b;
+}
+noInline(lessThanEqual);
+
+function greaterThan(a, b)
+{
+ return a > b;
+}
+noInline(greaterThan);
+
+function greaterThanEqual(a, b)
+{
+ return a >= b;
+}
+noInline(greaterThanEqual);
+
+function equal(a, b)
+{
+ return a == b;
+}
+noInline(equal);
+
+for (var i = 0; i < 1e3; ++i) {
+ for (let [a, b, res] of list) {
+ shouldBe(lessThan(a, b), result(lessThan, res));
+ shouldBe(lessThanEqual(a, b), result(lessThanEqual, res));
+ shouldBe(greaterThan(a, b), result(greaterThan, res));
+ shouldBe(greaterThanEqual(a, b), result(greaterThanEqual, res));
+ shouldBe(equal(a, b), result(equal, res));
+ }
+}
Added: trunk/JSTests/stress/dfg-ai-fold-bigint.js (0 => 260660)
--- trunk/JSTests/stress/dfg-ai-fold-bigint.js (rev 0)
+++ trunk/JSTests/stress/dfg-ai-fold-bigint.js 2020-04-24 19:19:23 UTC (rev 260660)
@@ -0,0 +1,90 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+function allAreTrue(list)
+{
+ for (let item of list)
+ shouldBe(item, true);
+}
+
+function allAreFalse(list)
+{
+ for (let item of list)
+ shouldBe(item, false);
+}
+
+function lessThan()
+{
+ return [0n < 2n, -10n < 20n, -10n < -2n, -100000000000000n < 0n, -100000000000000n < 10000n, -100000000000000n < -10000n, -1000000000000000000000n < -100000000000n, 1000000000000000000000n < 1000000000000000000000000n];
+}
+noInline(lessThan);
+
+function lessThanFalse()
+{
+ return [100000000000000000000n < 100000000000000000000n, 0n < 0n, 2n < 0n, 2n < 2n, -10n < -10n, 20n < -20n, -2n < -10n, 0n < -100000000000000n, -10000n < -100000000000000n, -100000000000n < -1000000000000000000000n, 1000000000000000000000000n < 1000000000000000000000n ];
+}
+noInline(lessThanFalse);
+
+function lessThanEqual()
+{
+ return [100000000000000000000n <= 100000000000000000000n, 0n <= 0n, 0n <= 2n, 2n <= 2n, -10n <= -10n, -20n <= 20n, -10n <= -2n, -100000000000000n <= 0n, -100000000000000n <= -10000n, -1000000000000000000000n <= -100000000000n, 1000000000000000000000n <= 1000000000000000000000000n ];
+}
+noInline(lessThanEqual);
+
+function lessThanEqualFalse()
+{
+ return [100000000000000000001n <= 100000000000000000000n, 1n <= 0n, 2n <= 0n, 3n <= 2n, -10n <= -11n, 20n <= -20n, -2n <= -10n, 0n <= -100000000000000n, -10000n <= -100000000000000n, -100000000000n <= -1000000000000000000000n, 1000000000000000000000000n <= 1000000000000000000000n ];
+}
+noInline(lessThanEqualFalse);
+
+function greaterThan()
+{
+ return [2n > 0n, 20n > -10n, -2n > -10n, 0n > -100000000000000n, 10000n > -100000000000000n, -10000n > -100000000000000n, -100000000000n > -1000000000000000000000n, 1000000000000000000000000n > 1000000000000000000000n ];
+}
+noInline(greaterThan);
+
+function greaterThanFalse()
+{
+ return [100000000000000000000n > 100000000000000000000n, 0n > 0n, 0n > 2n, 2n > 2n, -10n > -10n, -20n > 20n, -10n > -2n, -100000000000000n > 0n, -100000000000000n > -10000n, -1000000000000000000000n > -100000000000n, 1000000000000000000000n > 1000000000000000000000000n ];
+}
+noInline(greaterThanFalse);
+
+function greaterThanEqual()
+{
+ return [100000000000000000000n >= 100000000000000000000n, 0n >= 0n, 2n >= 0n, 2n >= 2n, -10n >= -10n, 20n >= -20n, -2n >= -10n, 0n >= -100000000000000n, -10000n >= -100000000000000n, -100000000000n >= -1000000000000000000000n, 1000000000000000000000000n >= 1000000000000000000000n ];
+}
+noInline(greaterThanEqual);
+
+function greaterThanEqualFalse()
+{
+ return [100000000000000000000n >= 100000000000000000001n, 0n >= 1n, 0n >= 2n, 2n >= 3n, -11n >= -10n, -20n >= 20n, -10n >= -2n, -100000000000000n >= 0n, -100000000000000n >= -10000n, -1000000000000000000000n >= -100000000000n, 1000000000000000000000n >= 1000000000000000000000000n ];
+}
+noInline(greaterThanEqualFalse);
+
+function equal()
+{
+ return [100000000000000000000n == 100000000000000000000n, 0n == 0n, 2n == 2n, -2n == -2n, -20n == -20n, -100000000000000n == -100000000000000n];
+}
+noInline(equal);
+
+function equalFalse()
+{
+ return [100000000000000000001n == 100000000000000000000n, 1n == 0n, -2n == 2n, 2n == -2n, -20n == 20n, -100000000000000n == 100000000000000n, 100000000000000n == -100000000000000n, -100000000000001n == -100000000000000n, 100000000000001n == 100000000000000n, -100000000000000n == 1n, 100000000000000n == 1n, -1n == 100000000000000n, 1n == -100000000000000n, -1n == -100000000000000n];
+}
+noInline(equalFalse);
+
+for (var i = 0; i < 1e4; ++i) {
+ allAreTrue(lessThan());
+ allAreTrue(lessThanEqual());
+ allAreTrue(greaterThan());
+ allAreTrue(greaterThanEqual());
+ allAreTrue(equal());
+
+ allAreFalse(lessThanFalse());
+ allAreFalse(lessThanEqualFalse());
+ allAreFalse(greaterThanFalse());
+ allAreFalse(greaterThanEqualFalse());
+ allAreFalse(equalFalse());
+}
Modified: trunk/Source/_javascript_Core/ChangeLog (260659 => 260660)
--- trunk/Source/_javascript_Core/ChangeLog 2020-04-24 18:42:53 UTC (rev 260659)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-04-24 19:19:23 UTC (rev 260660)
@@ -1,3 +1,47 @@
+2020-04-24 Yusuke Suzuki <[email protected]>
+
+ [JSC] DFG compare should speculate BigInt well
+ https://bugs.webkit.org/show_bug.cgi?id=210892
+
+ Reviewed by Saam Barati.
+
+ Compare operations in DFG does not support BigInt related speculations. As a result, DFG fixup phase emits DoubleRep for operands, and
+ causes OSR exit. This patch adds BigInt32, HeapBigInt, and AnyBigIntUse support to DFG compare operations to avoid OSR exits.
+ We also introduce JSBigInt::compareToInt32 to avoid allocating JSBigInt only for comparison, and optimize C++ runtime for JSBigInt comparison.
+
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+ * dfg/DFGDoesGC.cpp:
+ (JSC::DFG::doesGC):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileValueAdd):
+ (JSC::DFG::SpeculativeJIT::compileValueSub):
+ (JSC::DFG::SpeculativeJIT::compileValueMul):
+ (JSC::DFG::SpeculativeJIT::compare):
+ (JSC::DFG::SpeculativeJIT::genericJSValueNonPeepholeCompare):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompare): Deleted.
+ * dfg/DFGSpeculativeJIT.h:
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileBigInt32Compare):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compileCompareEq):
+ (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
+ (JSC::FTL::DFG::LowerDFGToB3::compare):
+ (JSC::FTL::DFG::LowerDFGToB3::genericJSValueCompare):
+ (JSC::FTL::DFG::LowerDFGToB3::nonSpeculativeCompare): Deleted.
+ * jit/AssemblyHelpers.h:
+ (JSC::AssemblyHelpers::unboxBigInt32):
+ * runtime/JSBigInt.cpp:
+ (JSC::JSBigInt::compareToInt32):
+ * runtime/JSBigInt.h:
+ (JSC::swapBigIntCompareResult):
+ * runtime/Operations.h:
+ (JSC::compareBigInt):
+ (JSC::compareBigInt32ToOtherPrimitive):
+ (JSC::bigIntCompare):
+
2020-04-24 Alexey Shvayka <[email protected]>
Proxy.revocable should not have [[Construct]] slot
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (260659 => 260660)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2020-04-24 18:42:53 UTC (rev 260659)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2020-04-24 19:19:23 UTC (rev 260660)
@@ -1855,23 +1855,45 @@
JSValue rightConst = forNode(node->child2()).value();
if (leftConst && rightConst) {
if (leftConst.isNumber() && rightConst.isNumber()) {
+ auto compareNumber = [&](double a, double b) {
+ switch (node->op()) {
+ case CompareLess:
+ return jsBoolean(a < b);
+ case CompareLessEq:
+ return jsBoolean(a <= b);
+ case CompareGreater:
+ return jsBoolean(a > b);
+ case CompareGreaterEq:
+ return jsBoolean(a >= b);
+ case CompareEq:
+ return jsBoolean(a == b);
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+ };
double a = leftConst.asNumber();
double b = rightConst.asNumber();
+ setConstant(node, compareNumber(a, b));
+ break;
+ }
+
+ if (leftConst.isBigInt() && rightConst.isBigInt()) {
switch (node->op()) {
case CompareLess:
- setConstant(node, jsBoolean(a < b));
+ setConstant(node, jsBoolean(bigIntCompareResult(compareBigInt(leftConst, rightConst), JSBigInt::ComparisonMode::LessThan)));
break;
case CompareLessEq:
- setConstant(node, jsBoolean(a <= b));
+ setConstant(node, jsBoolean(bigIntCompareResult(compareBigInt(leftConst, rightConst), JSBigInt::ComparisonMode::LessThanOrEqual)));
break;
case CompareGreater:
- setConstant(node, jsBoolean(a > b));
+ setConstant(node, jsBoolean(bigIntCompareResult(compareBigInt(rightConst, leftConst), JSBigInt::ComparisonMode::LessThan)));
break;
case CompareGreaterEq:
- setConstant(node, jsBoolean(a >= b));
+ setConstant(node, jsBoolean(bigIntCompareResult(compareBigInt(rightConst, leftConst), JSBigInt::ComparisonMode::LessThanOrEqual)));
break;
case CompareEq:
- setConstant(node, jsBoolean(a == b));
+ setConstant(node, jsBoolean(compareBigInt(leftConst, rightConst) == JSBigInt::ComparisonResult::Equal));
break;
default:
RELEASE_ASSERT_NOT_REACHED();
@@ -1947,6 +1969,9 @@
if (node->child1() == node->child2()) {
if (node->isBinaryUseKind(Int32Use) ||
node->isBinaryUseKind(Int52RepUse) ||
+ node->isBinaryUseKind(BigInt32Use) ||
+ node->isBinaryUseKind(HeapBigIntUse) ||
+ node->isBinaryUseKind(AnyBigIntUse) ||
node->isBinaryUseKind(StringUse) ||
node->isBinaryUseKind(BooleanUse) ||
node->isBinaryUseKind(SymbolUse) ||
Modified: trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp (260659 => 260660)
--- trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp 2020-04-24 18:42:53 UTC (rev 260659)
+++ trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp 2020-04-24 19:19:23 UTC (rev 260660)
@@ -434,11 +434,14 @@
case CompareLessEq:
case CompareGreater:
case CompareGreaterEq:
+ // FIXME: Add AnyBigIntUse and HeapBigIntUse specific optimizations in DFG / FTL code generation and ensure it does not perform GC.
+ // https://bugs.webkit.org/show_bug.cgi?id=210923
if (node->isBinaryUseKind(Int32Use)
#if USE(JSVALUE64)
|| node->isBinaryUseKind(Int52RepUse)
#endif
|| node->isBinaryUseKind(DoubleRepUse)
+ || node->isBinaryUseKind(BigInt32Use)
|| node->isBinaryUseKind(StringIdentUse)
)
return false;
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (260659 => 260660)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2020-04-24 18:42:53 UTC (rev 260659)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2020-04-24 19:19:23 UTC (rev 260660)
@@ -872,6 +872,26 @@
node->clearFlags(NodeMustGenerate);
break;
}
+ if (Node::shouldSpeculateHeapBigInt(node->child1().node(), node->child2().node())) {
+ fixEdge<HeapBigIntUse>(node->child1());
+ fixEdge<HeapBigIntUse>(node->child2());
+ node->clearFlags(NodeMustGenerate);
+ return;
+ }
+#if USE(BIGINT32)
+ if (Node::shouldSpeculateBigInt32(node->child1().node(), node->child2().node())) {
+ fixEdge<BigInt32Use>(node->child1());
+ fixEdge<BigInt32Use>(node->child2());
+ node->clearFlags(NodeMustGenerate);
+ return;
+ }
+ if (Node::shouldSpeculateBigInt(node->child1().node(), node->child2().node())) {
+ fixEdge<AnyBigIntUse>(node->child1());
+ fixEdge<AnyBigIntUse>(node->child2());
+ node->clearFlags(NodeMustGenerate);
+ return;
+ }
+#endif
if (Node::shouldSpeculateNumberOrBoolean(node->child1().node(), node->child2().node())) {
fixDoubleOrBooleanEdge(node->child1());
fixDoubleOrBooleanEdge(node->child2());
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (260659 => 260660)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2020-04-24 18:42:53 UTC (rev 260659)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2020-04-24 19:19:23 UTC (rev 260660)
@@ -4028,18 +4028,16 @@
if (node->isBinaryUseKind(BigInt32Use)) {
SpeculateBigInt32Operand left(this, leftChild);
SpeculateBigInt32Operand right(this, rightChild);
+ GPRTemporary result(this);
+ GPRTemporary temp(this);
- // FIXME: do we really need this extra register, or can we mutate left/right ?
- // FIXME: also, look into Reuse and other tricks for a more efficient generated code.
- GPRTemporary result(this);
+ GPRReg leftGPR = left.gpr();
+ GPRReg rightGPR = right.gpr();
GPRReg resultGPR = result.gpr();
- GPRTemporary temp(this);
GPRReg tempGPR = temp.gpr();
- m_jit.move(left.gpr(), resultGPR);
- m_jit.unboxBigInt32(resultGPR);
- m_jit.move(right.gpr(), tempGPR);
- m_jit.unboxBigInt32(tempGPR);
+ m_jit.unboxBigInt32(leftGPR, resultGPR);
+ m_jit.unboxBigInt32(rightGPR, tempGPR);
// FIXME: add some way to eliminate the overflow check
MacroAssembler::Jump check = m_jit.branchAdd32(MacroAssembler::Overflow, resultGPR, tempGPR, resultGPR);
@@ -4134,18 +4132,16 @@
if (node->binaryUseKind() == BigInt32Use) {
SpeculateBigInt32Operand left(this, node->child1());
SpeculateBigInt32Operand right(this, node->child2());
+ GPRTemporary result(this);
+ GPRTemporary temp(this);
- // FIXME: do we really need this extra register, or can we mutate left/right ?
- // FIXME: also, look into Reuse and other tricks for a more efficient generated code.
- GPRTemporary result(this);
+ GPRReg leftGPR = left.gpr();
+ GPRReg rightGPR = right.gpr();
GPRReg resultGPR = result.gpr();
- GPRTemporary temp(this);
GPRReg tempGPR = temp.gpr();
- m_jit.move(left.gpr(), resultGPR);
- m_jit.unboxBigInt32(resultGPR);
- m_jit.move(right.gpr(), tempGPR);
- m_jit.unboxBigInt32(tempGPR);
+ m_jit.unboxBigInt32(leftGPR, resultGPR);
+ m_jit.unboxBigInt32(rightGPR, tempGPR);
// FIXME: add some way to eliminate the overflow check
MacroAssembler::Jump check = m_jit.branchSub32(MacroAssembler::Overflow, resultGPR, tempGPR, resultGPR);
@@ -4984,18 +4980,16 @@
// FIXME: the code between compileValueAdd, compileValueSub and compileValueMul for BigInt32 is nearly identical, so try to get rid of the duplication.
SpeculateBigInt32Operand left(this, node->child1());
SpeculateBigInt32Operand right(this, node->child2());
+ GPRTemporary result(this);
+ GPRTemporary temp(this);
- // FIXME: do we really need this extra register, or can we mutate left/right ?
- // FIXME: also, look into Reuse and other tricks for a more efficient generated code.
- GPRTemporary result(this);
+ GPRReg leftGPR = left.gpr();
+ GPRReg rightGPR = right.gpr();
GPRReg resultGPR = result.gpr();
- GPRTemporary temp(this);
GPRReg tempGPR = temp.gpr();
- m_jit.move(left.gpr(), resultGPR);
- m_jit.unboxBigInt32(resultGPR);
- m_jit.move(right.gpr(), tempGPR);
- m_jit.unboxBigInt32(tempGPR);
+ m_jit.unboxBigInt32(leftGPR, resultGPR);
+ m_jit.unboxBigInt32(rightGPR, tempGPR);
// FIXME: add some way to eliminate the overflow check
MacroAssembler::Jump check = m_jit.branchMul32(MacroAssembler::Overflow, resultGPR, tempGPR, resultGPR);
@@ -6252,6 +6246,7 @@
return false;
}
#endif
+
#if USE(JSVALUE64)
if (node->isBinaryUseKind(Int52RepUse)) {
compileInt52Compare(node, condition);
@@ -6320,7 +6315,7 @@
}
}
- nonSpeculativeNonPeepholeCompare(node, condition, operation);
+ genericJSValueNonPeepholeCompare(node, condition, operation);
return false;
}
@@ -14115,11 +14110,13 @@
addSlowPathGenerator(WTFMove(slowPath));
}
-void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node* node, MacroAssembler::RelationalCondition cond, S_JITOperation_GJJ helperFunction)
+void SpeculativeJIT::genericJSValueNonPeepholeCompare(Node* node, MacroAssembler::RelationalCondition cond, S_JITOperation_GJJ helperFunction)
{
- ASSERT(node->isBinaryUseKind(UntypedUse));
- JSValueOperand arg1(this, node->child1());
- JSValueOperand arg2(this, node->child2());
+ ASSERT(node->isBinaryUseKind(UntypedUse) || node->isBinaryUseKind(AnyBigIntUse) || node->isBinaryUseKind(HeapBigIntUse));
+ JSValueOperand arg1(this, node->child1(), ManualOperandSpeculation);
+ JSValueOperand arg2(this, node->child2(), ManualOperandSpeculation);
+ speculate(node, node->child1());
+ speculate(node, node->child2());
JSValueRegs arg1Regs = arg1.jsValueRegs();
JSValueRegs arg2Regs = arg2.jsValueRegs();
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (260659 => 260660)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2020-04-24 18:42:53 UTC (rev 260659)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2020-04-24 19:19:23 UTC (rev 260660)
@@ -743,7 +743,7 @@
void nonSpeculativePeepholeBranchNullOrUndefined(Edge operand, Node* branchNode);
void nonSpeculativePeepholeBranch(Node*, Node* branchNode, MacroAssembler::RelationalCondition, S_JITOperation_GJJ helperFunction);
- void nonSpeculativeNonPeepholeCompare(Node*, MacroAssembler::RelationalCondition, S_JITOperation_GJJ helperFunction);
+ void genericJSValueNonPeepholeCompare(Node*, MacroAssembler::RelationalCondition, S_JITOperation_GJJ helperFunction);
void nonSpeculativePeepholeStrictEq(Node*, Node* branchNode, bool invert = false);
void genericJSValueNonPeepholeStrictEq(Node*, bool invert = false);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (260659 => 260660)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2020-04-24 18:42:53 UTC (rev 260659)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2020-04-24 19:19:23 UTC (rev 260660)
@@ -1753,21 +1753,16 @@
if (condition == MacroAssembler::Equal || condition == MacroAssembler::NotEqual) {
// No need to unbox the operands, since the tag bits are identical
- m_jit.compare64(condition, op1.gpr(), op2.gpr(), result.gpr());
+ m_jit.compare64(condition, op1GPR, op2GPR, resultGPR);
} else {
GPRTemporary temp(this);
GPRReg tempGPR = temp.gpr();
- m_jit.move(op1GPR, tempGPR);
- m_jit.unboxBigInt32(tempGPR);
- m_jit.move(op2GPR, resultGPR);
- m_jit.unboxBigInt32(resultGPR);
- m_jit.compare64(condition, tempGPR, resultGPR, resultGPR);
+ m_jit.unboxBigInt32(op1GPR, tempGPR);
+ m_jit.unboxBigInt32(op2GPR, resultGPR);
+ m_jit.compare32(condition, tempGPR, resultGPR, resultGPR);
}
-
- // If we add a DataFormatBool, we should use it here.
- m_jit.or32(TrustedImm32(JSValue::ValueFalse), result.gpr());
- jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean);
+ unblessedBooleanResult(resultGPR, node);
}
void SpeculativeJIT::compilePeepHoleBigInt32Branch(Node* node, Node* branchNode, JITCompiler::RelationalCondition condition)
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (260659 => 260660)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2020-04-24 18:42:53 UTC (rev 260659)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2020-04-24 19:19:23 UTC (rev 260660)
@@ -8661,7 +8661,7 @@
}
DFG_ASSERT(m_graph, m_node, m_node->isBinaryUseKind(UntypedUse), m_node->child1().useKind(), m_node->child2().useKind());
- nonSpeculativeCompare(
+ genericJSValueCompare(
[&] (LValue left, LValue right) {
return m_out.equal(left, right);
},
@@ -8949,7 +8949,7 @@
// FIXME: we can do something much smarter here, see the DFGSpeculativeJIT approach in e.g. SpeculativeJIT::nonSpeculativePeepholeStrictEq
DFG_ASSERT(m_graph, m_node, m_node->isBinaryUseKind(UntypedUse), m_node->child1().useKind(), m_node->child2().useKind());
- nonSpeculativeCompare(
+ genericJSValueCompare(
[&] (LValue left, LValue right) {
return m_out.equal(left, right);
},
@@ -13556,6 +13556,13 @@
return;
}
+ if (m_node->isBinaryUseKind(BigInt32Use)) {
+ LValue left = lowBigInt32(m_node->child1());
+ LValue right = lowBigInt32(m_node->child2());
+ setBoolean(intFunctor(unboxBigInt32(left), unboxBigInt32(right)));
+ return;
+ }
+
if (m_node->isBinaryUseKind(StringIdentUse)) {
LValue left = lowStringIdent(m_node->child1());
LValue right = lowStringIdent(m_node->child2());
@@ -13576,8 +13583,8 @@
return;
}
- DFG_ASSERT(m_graph, m_node, m_node->isBinaryUseKind(UntypedUse), m_node->child1().useKind(), m_node->child2().useKind());
- nonSpeculativeCompare(intFunctor, fallbackFunction);
+ DFG_ASSERT(m_graph, m_node, m_node->isBinaryUseKind(UntypedUse) || m_node->isBinaryUseKind(HeapBigIntUse) || m_node->isBinaryUseKind(AnyBigIntUse), m_node->child1().useKind(), m_node->child2().useKind());
+ genericJSValueCompare(intFunctor, fallbackFunction);
}
void compileStringSlice()
@@ -14547,11 +14554,13 @@
}
template<typename IntFunctor>
- void nonSpeculativeCompare(const IntFunctor& intFunctor, S_JITOperation_GJJ helperFunction)
+ void genericJSValueCompare(const IntFunctor& intFunctor, S_JITOperation_GJJ helperFunction)
{
JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
- LValue left = lowJSValue(m_node->child1());
- LValue right = lowJSValue(m_node->child2());
+ LValue left = lowJSValue(m_node->child1(), ManualOperandSpeculation);
+ LValue right = lowJSValue(m_node->child2(), ManualOperandSpeculation);
+ speculate(m_node->child1());
+ speculate(m_node->child2());
LBasicBlock leftIsInt = m_out.newBlock();
LBasicBlock fastPath = m_out.newBlock();
Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.h (260659 => 260660)
--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.h 2020-04-24 18:42:53 UTC (rev 260659)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.h 2020-04-24 19:19:23 UTC (rev 260660)
@@ -1398,9 +1398,14 @@
#endif // USE(JSVALUE64)
#if USE(BIGINT32)
- void unboxBigInt32(GPRReg gpr)
+ void unboxBigInt32(GPRReg src, GPRReg dest)
{
- urshift64(trustedImm32ForShift(Imm32(16)), gpr);
+#if CPU(ARM64)
+ urshift64(src, trustedImm32ForShift(Imm32(16)), dest);
+#else
+ move(src, dest);
+ urshift64(trustedImm32ForShift(Imm32(16)), dest);
+#endif
}
void boxBigInt32(GPRReg gpr)
Modified: trunk/Source/_javascript_Core/runtime/JSBigInt.cpp (260659 => 260660)
--- trunk/Source/_javascript_Core/runtime/JSBigInt.cpp 2020-04-24 18:42:53 UTC (rev 260659)
+++ trunk/Source/_javascript_Core/runtime/JSBigInt.cpp 2020-04-24 19:19:23 UTC (rev 260660)
@@ -2020,6 +2020,36 @@
return (this->length() == 1) && (this->sign() == (value < 0)) && (this->digit(0) == static_cast<Digit>(std::abs(static_cast<int64_t>(value))));
}
+JSBigInt::ComparisonResult JSBigInt::compareToInt32(int32_t value)
+{
+ bool xSign = sign();
+ bool ySign = value < 0;
+
+ if (xSign != ySign)
+ return xSign ? ComparisonResult::LessThan : ComparisonResult::GreaterThan;
+ if (isZero()) {
+ ASSERT(!xSign);
+ ASSERT(!ySign);
+ if (value == 0)
+ return ComparisonResult::Equal;
+ return ComparisonResult::LessThan;
+ }
+
+ if (length() != 1)
+ return xSign ? ComparisonResult::LessThan : ComparisonResult::GreaterThan;
+
+ uint64_t value64 = 0;
+ if (xSign)
+ value64 = static_cast<uint64_t>(-static_cast<int64_t>(value));
+ else
+ value64 = value;
+ if (digit(0) == value64)
+ return ComparisonResult::Equal;
+ if (digit(0) < value64)
+ return xSign ? ComparisonResult::GreaterThan : ComparisonResult::LessThan;
+ return xSign ? ComparisonResult::LessThan : ComparisonResult::GreaterThan;
+}
+
JSBigInt::ComparisonResult JSBigInt::compareToDouble(JSBigInt* x, double y)
{
// This algorithm expect that the double format is IEEE 754
Modified: trunk/Source/_javascript_Core/runtime/JSBigInt.h (260659 => 260660)
--- trunk/Source/_javascript_Core/runtime/JSBigInt.h 2020-04-24 18:42:53 UTC (rev 260659)
+++ trunk/Source/_javascript_Core/runtime/JSBigInt.h 2020-04-24 19:19:23 UTC (rev 260660)
@@ -124,6 +124,9 @@
JS_EXPORT_PRIVATE static bool equals(JSBigInt*, JSBigInt*);
bool equalsToNumber(JSValue);
JS_EXPORT_PRIVATE bool equalsToInt32(int32_t);
+ JS_EXPORT_PRIVATE ComparisonResult compareToInt32(int32_t);
+ JS_EXPORT_PRIVATE bool lessThanInt32(int32_t);
+ JS_EXPORT_PRIVATE bool lessThanEqualInt32(int32_t);
static ComparisonResult compare(JSBigInt* x, JSBigInt* y);
bool getPrimitiveNumber(JSGlobalObject*, double& number, JSValue& result) const;
@@ -287,4 +290,24 @@
dataStorage()[n] = value;
}
+#if !ASSERT_ENABLED
+IGNORE_RETURN_TYPE_WARNINGS_BEGIN
+#endif
+ALWAYS_INLINE JSBigInt::ComparisonResult invertBigIntCompareResult(JSBigInt::ComparisonResult comparisonResult)
+{
+ switch (comparisonResult) {
+ case JSBigInt::ComparisonResult::GreaterThan:
+ return JSBigInt::ComparisonResult::LessThan;
+ case JSBigInt::ComparisonResult::LessThan:
+ return JSBigInt::ComparisonResult::GreaterThan;
+ case JSBigInt::ComparisonResult::Equal:
+ case JSBigInt::ComparisonResult::Undefined:
+ return comparisonResult;
+ }
+ ASSERT_NOT_REACHED();
+}
+#if !ASSERT_ENABLED
+IGNORE_RETURN_TYPE_WARNINGS_END
+#endif
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/Operations.h (260659 => 260660)
--- trunk/Source/_javascript_Core/runtime/Operations.h 2020-04-24 18:42:53 UTC (rev 260659)
+++ trunk/Source/_javascript_Core/runtime/Operations.h 2020-04-24 19:19:23 UTC (rev 260660)
@@ -238,6 +238,32 @@
return ropeBuilder.release();
}
+ALWAYS_INLINE JSBigInt::ComparisonResult compareBigInt(JSValue left, JSValue right)
+{
+ ASSERT(left.isBigInt());
+ ASSERT(right.isBigInt());
+#if USE(BIGINT32)
+ if (left.isBigInt32()) {
+ if (right.isBigInt32()) {
+ int32_t leftInt32 = left.bigInt32AsInt32();
+ int32_t rightInt32 = right.bigInt32AsInt32();
+ if (leftInt32 == rightInt32)
+ return JSBigInt::ComparisonResult::Equal;
+ if (leftInt32 < rightInt32)
+ return JSBigInt::ComparisonResult::LessThan;
+ return JSBigInt::ComparisonResult::GreaterThan;
+ }
+ ASSERT(right.isHeapBigInt());
+ return invertBigIntCompareResult(right.asHeapBigInt()->compareToInt32(left.bigInt32AsInt32()));
+ }
+ if (right.isBigInt32()) {
+ ASSERT(left.isHeapBigInt());
+ return left.asHeapBigInt()->compareToInt32(right.bigInt32AsInt32());
+ }
+#endif
+ return JSBigInt::compare(left.asHeapBigInt(), right.asHeapBigInt());
+}
+
ALWAYS_INLINE JSBigInt::ComparisonResult compareBigIntToOtherPrimitive(JSGlobalObject* globalObject, JSBigInt* v1, JSValue primValue)
{
VM& vm = globalObject->vm();
@@ -267,6 +293,46 @@
return JSBigInt::compareToDouble(v1, numberValue);
}
+ALWAYS_INLINE JSBigInt::ComparisonResult compareBigInt32ToOtherPrimitive(JSGlobalObject* globalObject, int32_t v1, JSValue primValue)
+{
+ VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ ASSERT(primValue.isPrimitive());
+ ASSERT(!primValue.isBigInt());
+
+ auto compare = [&] (auto v1, auto v2) {
+ static_assert(std::is_same_v<decltype(v1), decltype(v2)>);
+ if (v1 == v2)
+ return JSBigInt::ComparisonResult::Equal;
+ if (v1 < v2)
+ return JSBigInt::ComparisonResult::LessThan;
+ return JSBigInt::ComparisonResult::GreaterThan;
+ };
+
+ if (primValue.isString()) {
+ JSValue bigIntValue = JSBigInt::stringToBigInt(globalObject, asString(primValue)->value(globalObject));
+ RETURN_IF_EXCEPTION(scope, JSBigInt::ComparisonResult::Undefined);
+ if (!bigIntValue)
+ return JSBigInt::ComparisonResult::Undefined;
+
+ if (bigIntValue.isHeapBigInt())
+ return invertBigIntCompareResult(bigIntValue.asHeapBigInt()->compareToInt32(v1));
+
+ ASSERT(bigIntValue.isBigInt32());
+#if USE(BIGINT32)
+ return compare(v1, bigIntValue.bigInt32AsInt32());
+#endif
+ }
+
+ // Note that 0n <=> -0.0 is handling -0.0 as +0.
+ double numberValue = primValue.toNumber(globalObject);
+ RETURN_IF_EXCEPTION(scope, JSBigInt::ComparisonResult::Undefined);
+ if (std::isnan(numberValue))
+ return JSBigInt::ComparisonResult::Undefined;
+ return compare(static_cast<double>(v1), numberValue);
+}
+
ALWAYS_INLINE bool bigIntCompareResult(JSBigInt::ComparisonResult comparisonResult, JSBigInt::ComparisonMode comparisonMode)
{
if (comparisonMode == JSBigInt::ComparisonMode::LessThan)
@@ -284,47 +350,38 @@
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
+ if (v1.isBigInt() && v2.isBigInt())
+ return bigIntCompareResult(compareBigInt(v1, v2), comparisonMode);
+
#if USE(BIGINT32)
- if (v1.isBigInt32() && v2.isBigInt32()) {
- if (comparisonMode == JSBigInt::ComparisonMode::LessThan)
- return v1.bigInt32AsInt32() < v2.bigInt32AsInt32();
- ASSERT(comparisonMode == JSBigInt::ComparisonMode::LessThanOrEqual);
- return v1.bigInt32AsInt32() <= v2.bigInt32AsInt32();
+ if (v1.isBigInt32()) {
+ ASSERT(!v2.isBigInt());
+ auto comparisonResult = compareBigInt32ToOtherPrimitive(globalObject, v1.bigInt32AsInt32(), v2);
+ RETURN_IF_EXCEPTION(scope, false);
+ return bigIntCompareResult(comparisonResult, comparisonMode);
}
+ if (v2.isBigInt32()) {
+ ASSERT(!v1.isBigInt());
+ auto comparisonResult = compareBigInt32ToOtherPrimitive(globalObject, v2.bigInt32AsInt32(), v1);
+ RETURN_IF_EXCEPTION(scope, false);
+ return bigIntCompareResult(invertBigIntCompareResult(comparisonResult), comparisonMode);
+ }
+ ASSERT(!v1.isBigInt32() && !v2.isBigInt32());
#endif
- JSBigInt* v1HeapBigInt = nullptr;
- JSBigInt* v2HeapBigInt = nullptr;
- // FIXME: have some fast-ish path for a comparison between a small and a large big-int
- if (v1.isHeapBigInt())
- v1HeapBigInt = v1.asHeapBigInt();
-#if USE(BIGINT32)
- else if (v1.isBigInt32())
- v1HeapBigInt = JSBigInt::createFrom(vm, v1.bigInt32AsInt32());
-#endif
-
- if (v2.isHeapBigInt())
- v2HeapBigInt = v2.asHeapBigInt();
-#if USE(BIGINT32)
- else if (v2.isBigInt32())
- v2HeapBigInt = JSBigInt::createFrom(vm, v2.bigInt32AsInt32());
-#endif
-
- if (v1HeapBigInt && v2HeapBigInt)
- return bigIntCompareResult(JSBigInt::compare(v1HeapBigInt, v2HeapBigInt), comparisonMode);
-
- if (v1HeapBigInt) {
- auto comparisonResult = compareBigIntToOtherPrimitive(globalObject, v1HeapBigInt, v2);
+ if (v1.isHeapBigInt()) {
+ ASSERT(!v2.isBigInt());
+ auto comparisonResult = compareBigIntToOtherPrimitive(globalObject, v1.asHeapBigInt(), v2);
RETURN_IF_EXCEPTION(scope, false);
return bigIntCompareResult(comparisonResult, comparisonMode);
}
- auto comparisonResult = compareBigIntToOtherPrimitive(globalObject, v2HeapBigInt, v1);
+ // Here we check inverted because BigInt is the v2
+ ASSERT(!v1.isBigInt());
+ ASSERT(v2.isHeapBigInt());
+ auto comparisonResult = compareBigIntToOtherPrimitive(globalObject, v2.asHeapBigInt(), v1);
RETURN_IF_EXCEPTION(scope, false);
- // Here we check inverted because BigInt is the v2
- if (comparisonMode == JSBigInt::ComparisonMode::LessThan)
- return comparisonResult == JSBigInt::ComparisonResult::GreaterThan;
- return comparisonResult == JSBigInt::ComparisonResult::GreaterThan || comparisonResult == JSBigInt::ComparisonResult::Equal;
+ return bigIntCompareResult(invertBigIntCompareResult(comparisonResult), comparisonMode);
}
ALWAYS_INLINE bool toPrimitiveNumeric(JSGlobalObject* globalObject, JSValue v, JSValue& p, double& n)