WebKit Bugzilla
Attachment 341722 Details for
Bug 185929
: [ESNext][BigInt] Implement support for "=<" and ">=" relational operation
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for landing
big-int-less-than-or-equal.diff (text/plain), 35.25 KB, created by
Caio Lima
on 2018-05-31 18:48:11 PDT
(
hide
)
Description:
Patch for landing
Filename:
MIME Type:
Creator:
Caio Lima
Created:
2018-05-31 18:48:11 PDT
Size:
35.25 KB
patch
obsolete
>diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog >index aa28cad..a56ae14 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,20 @@ >+2018-05-30 Caio Lima <ticaiolima@gmail.com> >+ >+ [ESNext][BigInt] Implement support for "=<" and ">=" relational operation >+ https://bugs.webkit.org/show_bug.cgi?id=185929 >+ >+ Reviewed by Yusuke Suzuki. >+ >+ * bigIntTests.yaml: >+ * stress/big-int-greater-than-or-equal-jit.js: Added. >+ * stress/big-int-greater-than-or-equal-order-of-evaluation.js: Added. >+ * stress/big-int-greater-than-or-equal-wrapped-values.js: Added. >+ * stress/big-int-greater-than-or-equal.js: Added. >+ * stress/big-int-less-than-or-equal-general.js: Added. >+ * stress/big-int-less-than-or-equal-jit.js: Added. >+ * stress/big-int-less-than-or-equal-order-of-evaluation.js: Added. >+ * stress/big-int-less-than-or-equal-wrapped-values.js: Added. >+ > 2018-05-30 Keith Miller <keith_miller@apple.com> > > Unreviewed, uncomment erroneously commented test code. >diff --git a/JSTests/bigIntTests.yaml b/JSTests/bigIntTests.yaml >index cafa96a..756e49b 100644 >--- a/JSTests/bigIntTests.yaml >+++ b/JSTests/bigIntTests.yaml >@@ -139,6 +139,30 @@ > - path: stress/big-int-no-conversion-to-number.js > cmd: runBigIntEnabled > >+- path: stress/big-int-greater-than-or-equal-general.js >+ cmd: runBigIntEnabled >+ >+- path: stress/big-int-greater-than-or-equal-jit.js >+ cmd: runBigIntEnabled >+ >+- path: stress/big-int-greater-than-or-equal-order-of-evaluation.js >+ cmd: runBigIntEnabled >+ >+- path: stress/big-int-greater-than-or-equal-wrapped-values.js >+ cmd: runBigIntEnabled >+ >+- path: stress/big-int-less-than-or-equal-jit.js >+ cmd: runBigIntEnabled >+ >+- path: stress/big-int-less-than-or-equal-order-of-evaluation.js >+ cmd: runBigIntEnabled >+ >+- path: stress/big-int-less-than-or-equal-wrapped-values.js >+ cmd: runBigIntEnabled >+ >+- path: stress/big-int-less-than-or-equal-general.js >+ cmd: runBigIntEnabled >+ > - path: stress/big-int-mod-memory-stress.js > cmd: runBigIntEnabled > >diff --git a/JSTests/stress/big-int-greater-than-or-equal-jit.js b/JSTests/stress/big-int-greater-than-or-equal-jit.js >new file mode 100644 >index 0000000..d37fe51 >--- /dev/null >+++ b/JSTests/stress/big-int-greater-than-or-equal-jit.js >@@ -0,0 +1,24 @@ >+//@ runBigIntEnabled >+ >+function assert(a) { >+ if (!a) >+ throw new Error("Bad assertion"); >+} >+ >+function greaterThanOrEqualTest(a, b) { >+ return a >= b; >+} >+noInline(greaterThanOrEqualTest); >+ >+for (let i = 0; i < 100000; i++) { >+ assert(greaterThanOrEqualTest(3n, 4) === false); >+} >+ >+for (let i = 0; i < 100000; i++) { >+ assert(greaterThanOrEqualTest(3n, 4n) === false); >+} >+ >+for (let i = 0; i < 100000; i++) { >+ assert(greaterThanOrEqualTest(3n, "4") === false); >+} >+ >diff --git a/JSTests/stress/big-int-greater-than-or-equal-order-of-evaluation.js b/JSTests/stress/big-int-greater-than-or-equal-order-of-evaluation.js >new file mode 100644 >index 0000000..0e8ac85 >--- /dev/null >+++ b/JSTests/stress/big-int-greater-than-or-equal-order-of-evaluation.js >@@ -0,0 +1,55 @@ >+//@ runBigIntEnabled >+ >+function assert(v, e, m) { >+ if (v !== e) >+ throw new Error(m); >+} >+ >+let o = { >+ [Symbol.toPrimitive]: function() { >+ throw new Error("Calling @toPrimitive"); >+ } >+} >+ >+try { >+ o >= Symbol(2); >+ assert(true, false, "") >+} catch(e) { >+ assert(e.message, "Calling @toPrimitive", "Bad Exception when object is left operand"); >+} >+ >+try { >+ Symbol(2) >= o; >+ assert(true, false, "") >+} catch(e) { >+ assert(e instanceof TypeError, true, "Bad Exception when Symbol is left operand"); >+} >+ >+o = { >+ [Symbol.toPrimitive]: function() { >+ return 2n; >+ }, >+ >+ toString: function() { >+ throw new Error("Should never call toString"); >+ }, >+ >+ valueOf: function() { >+ throw new Error("Should never call valueOf"); >+ } >+} >+ >+assert(o >= 3n, false, "ToPrimitive(2n) > 3n"); >+ >+o = { >+ toString: function() { >+ throw new Error("Should never call toString"); >+ }, >+ >+ valueOf: function() { >+ return 2n; >+ } >+} >+ >+assert(o >= 3n, false, "valueOf(2n) > 3n"); >+ >diff --git a/JSTests/stress/big-int-greater-than-or-equal-wrapped-values.js b/JSTests/stress/big-int-greater-than-or-equal-wrapped-values.js >new file mode 100644 >index 0000000..597b2cf >--- /dev/null >+++ b/JSTests/stress/big-int-greater-than-or-equal-wrapped-values.js >@@ -0,0 +1,63 @@ >+//@ runBigIntEnabled >+ >+function assert(v, e, m) { >+ if (v !== e) >+ throw new Error(m); >+} >+ >+assert(Object(2n) >= 1n, true, "Object(2n) >= 1n"); >+assert(1n >= Object(2n), false, "1n >= Object(2n)"); >+assert(Object(2n) >= Object(1n), true, "Object(2n) >= Object(1n)"); >+assert(Object(1n) >= Object(2n), false, "Object(1n) >= Object(2n)"); >+ >+let o = { >+ [Symbol.toPrimitive]: function() { >+ return 2n; >+ } >+} >+ >+let o2 = { >+ [Symbol.toPrimitive]: function() { >+ return 1n; >+ } >+} >+ >+assert(o >= 1n, true, "ToPrimitive(2n) >= 1n"); >+assert(1n >= o, false, "1n >= ToPrimitive(2n)"); >+assert(o >= o2, true, "ToPrimitive(2n) >= ToPrimitive(1n)"); >+assert(o2 >= o, false, "ToPrimitive(1n) >= ToPrimitive(2n)"); >+ >+o = { >+ valueOf: function() { >+ return 2n; >+ } >+} >+ >+o2 = { >+ valueOf: function() { >+ return 1n; >+ } >+} >+ >+assert(o >= 1n, true, "valueOf(2n) >= 1n"); >+assert(1n >= o, false, "1n >= valueOf(2n)"); >+assert(o >= o2, true, "valueOf(2n) >= valueOf(1n)"); >+assert(o2 >= o, false, "valueOf(1n) >= valueOf(2n)"); >+ >+o = { >+ toString: function() { >+ return 2n; >+ } >+} >+ >+o2 = { >+ toString: function() { >+ return 1n; >+ } >+} >+ >+assert(o >= 1n, true, "toString(2n) >= 1n"); >+assert(1n >= o, false, "1n >= ToPrimitive(2n)"); >+assert(o >= o2, true, "toString(2n) < toString(1n)"); >+assert(o2 >= o, false, "toString(1n) < toString(2n)"); >+ >diff --git a/JSTests/stress/big-int-greater-than-or-equal.js b/JSTests/stress/big-int-greater-than-or-equal.js >new file mode 100644 >index 0000000..7fb523a >--- /dev/null >+++ b/JSTests/stress/big-int-greater-than-or-equal.js >@@ -0,0 +1,140 @@ >+//@ runBigIntEnabled >+ >+// Copyright (C) 2017 Josh Wolfe. All rights reserved. >+// Copyright (C) 2018 Igalia, S.L. All rights reserved. >+// This code is governed by the BSD license found in the LICENSE file. >+ >+function assert(v, e, m) { >+ if (v !== e) >+ throw new Error(m); >+} >+ >+assert(0n >= 0n, true, "0n >= 0n"); >+assert(1n >= 1n, true, "1n >= 1n"); >+assert(BigInt("-1") >= BigInt("-1"), true, "-1n >= -1n"); >+assert(0n >= BigInt("-0"), true, "0n >= -0n"); >+assert(BigInt("-0") >= 0n, true, "-0n >= 0n"); >+assert(0n >= 1n, false, "0n >= 1n"); >+assert(1n >= 0n, true, "1n >= 0n"); >+assert(0n >= BigInt("-1"), true, "0n >= -1n"); >+assert(BigInt("-1") >= 0n, false, "-1n >= 0n"); >+assert(1n >= BigInt("-1"), true, "1n >= -1n"); >+assert(BigInt("-1") >= 1n, false, "-1n >= 1n"); >+assert(0x1fffffffffffff01n >= 0x1fffffffffffff02n, false, "0x1fffffffffffff01n >= 0x1fffffffffffff02n"); >+assert(0x1fffffffffffff02n >= 0x1fffffffffffff01n, true, "0x1fffffffffffff02n >= 0x1fffffffffffff01n"); >+assert(BigInt("-2305843009213693697") >= BigInt("-2305843009213693698"), true, "-2305843009213693697n >= -2305843009213693698n"); >+assert(BigInt("-2305843009213693698") >= BigInt("-2305843009213693697"), false, "-2305843009213693698n >= -2305843009213693697n"); >+assert(0x10000000000000000n >= 0n, true, "0x10000000000000000n >= 0n"); >+assert(0n >= 0x10000000000000000n, false, "0n >= 0x10000000000000000n"); >+assert(0x10000000000000000n >= 1n, true, "0x10000000000000000n >= 1n"); >+assert(1n >= 0x10000000000000000n, false, "1n >= 0x10000000000000000n"); >+assert(0x10000000000000000n >= BigInt("-1"), true, "0x10000000000000000n >= -1n"); >+assert(BigInt("-1") >= 0x10000000000000000n, false, "-1n >= 0x10000000000000000n"); >+assert(0x10000000000000001n >= 0n, true, "0x10000000000000001n >= 0n"); >+assert(0n >= 0x10000000000000001n, false, "0n >= 0x10000000000000001n"); >+assert(BigInt("-18446744073709551616") >= 0n, false, "-18446744073709551616n >= 0n"); >+assert(0n >= BigInt("-18446744073709551616"), true, "0n >= -18446744073709551616n"); >+assert(BigInt("-18446744073709551616") >= 1n, false, "-18446744073709551616n >= 1n"); >+assert(1n >= BigInt("-18446744073709551616"), true, "1n >= -18446744073709551616n"); >+assert(BigInt("-18446744073709551616") >= BigInt("-1"), false, "-18446744073709551616n >= -1n"); >+assert(BigInt("-1") >= BigInt("-18446744073709551616"), true, "-1n >= -18446744073709551616n"); >+assert(BigInt("-18446744073709551617") >= 0n, false, "-18446744073709551617n >= 0n"); >+assert(0n >= BigInt("-18446744073709551617"), true, "0n >= -18446744073709551617n"); >+assert(0x10000000000000000n >= 0x100000000n, true, "0x10000000000000000n >= 0x100000000n"); >+assert(0x100000000n >= 0x10000000000000000n, false, "0x100000000n >= 0x10000000000000000n"); >+ >+// BigInt - String >+ >+assert(0n >= "0", true, "0n >= '0'"); >+assert("0" >= 0n, true, "'0' >= 0n"); >+assert(0n >= "1", false, "0n >= '1'"); >+assert("0" >= 1n, false, "'0' >= 1n"); >+assert(1n >= "0", true, "1n >= '0'"); >+assert("1" >= 0n, true, "'1' >= 0n"); >+assert(0n >= "", true, "0n >= ''"); >+assert("" >= 0n, true, "'' >= 0n"); >+assert(0n >= "1", false, "0n >= '1'"); >+assert("" >= 1n, false, "'' >= 1n"); >+assert(1n >= "", true, "1n >= ''"); >+assert(1n >= "1", true, "1n >= '1'"); >+assert("1" >= 1n, true, "'1' >= 1n"); >+assert(1n >= "-1", true, "1n >= '-1'"); >+assert("1" >= BigInt("-1"), true, "'1' >= -1n"); >+assert(BigInt("-1") >= "1", false, "-1n >= '1'"); >+assert("-1" >= 1n, false, "'-1' >= 1n"); >+assert(BigInt("-1") >= "-1", true, "-1n >= '-1'"); >+assert("-1" >= BigInt("-1"), true, "'-1' >= -1n"); >+assert(9007199254740993n >= "9007199254740992", true, "9007199254740993n >= '9007199254740992'"); >+assert("9007199254740993" >= 9007199254740992n, true, "'9007199254740993' >= 9007199254740992n"); >+assert(BigInt("-9007199254740992") >= "-9007199254740993", true, "-9007199254740992n >= '-9007199254740993'"); >+assert("-9007199254740992" >= BigInt("-9007199254740993"), true, "'-9007199254740992' >= -9007199254740993n"); >+assert("0x10" >= 14n, true, "'0x10' >= 3n"); >+assert("0b10" >= 2n, true, "'0b10' >= 2n"); >+assert("0b10" >= 1n, true, "'0b10' >= 1n"); >+ >+// Invalid String >+ >+assert("b10" >= 2n, false, "'b10' >= 2n"); >+assert("bbb10" >= 2n, false, "'bbb10' >= 2n"); >+ >+// BigInt - Number >+ >+assert(0n >= 0, true, "0n >= 0"); >+assert(0 >= 0n, true, "0 >= 0n"); >+assert(0n >= -0, true, "0n >= -0"); >+assert(-0 >= 0n, true, "-0 >= 0n"); >+assert(0n >= 0.000000000001, false, "0n >= 0.000000000001"); >+assert(0.000000000001 >= 0n, true, "0.000000000001 >= 0n"); >+assert(0n >= 1, false, "0n >= 1"); >+assert(1 >= 0n, true, "1 >= 0n"); >+assert(1n >= 0, true, "1n >= 0"); >+assert(0 >= 1n, false, "0 >= 1n"); >+assert(1n >= 0.999999999999, true, "1n >= 0.999999999999"); >+assert(0.999999999999 >= 1n, false, "0.999999999999 >= 1n"); >+assert(1n >= 1, true, "1n >= 1"); >+assert(1 >= 1n, true, "1 >= 1n"); >+assert(0n >= Number.MIN_VALUE, false, "0n >= Number.MIN_VALUE"); >+assert(Number.MIN_VALUE >= 0n, true, "Number.MIN_VALUE >= 0n"); >+assert(0n >= -Number.MIN_VALUE, true, "0n >= -Number.MIN_VALUE"); >+assert(-Number.MIN_VALUE >= 0n, false, "-Number.MIN_VALUE >= 0n"); >+assert(BigInt("-10") >= Number.MIN_VALUE, false, "-10n >= Number.MIN_VALUE"); >+assert(Number.MIN_VALUE >= BigInt("-10"), true, "Number.MIN_VALUE >= -10n"); >+assert(1n >= Number.MAX_VALUE, false, "1n >= Number.MAX_VALUE"); >+assert(Number.MAX_VALUE >= 1n, true, "Number.MAX_VALUE >= 1n"); >+assert(1n >= -Number.MAX_VALUE, true, "1n >= -Number.MAX_VALUE"); >+assert(-Number.MAX_VALUE >= 1n, false, "-Number.MAX_VALUE >= 1n"); >+assert(0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn >= Number.MAX_VALUE, false, "0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn >= Number.MAX_VALUE"); >+assert(Number.MAX_VALUE >= 0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn, true, "Number.MAX_VALUE >= 0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn"); >+assert(0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n >= Number.MAX_VALUE, true, "0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n >= Number.MAX_VALUE"); >+assert(Number.MAX_VALUE >= 0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n, false, "Number.MAX_VALUE >= 0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n"); >+assert(1n >= Infinity, false, "1n >= Infinity"); >+assert(Infinity >= 1n, true, "Infinity >= 1n"); >+assert(BigInt("-1") >= Infinity, false, "-1n >= Infinity"); >+assert(Infinity >= BigInt("-1"), true, "Infinity >= -1n"); >+assert(1n >= -Infinity, true, "1n >= -Infinity"); >+assert(-Infinity >= 1n, false, "-Infinity >= 1n"); >+assert(BigInt("-1") >= -Infinity, true, "-1n >= -Infinity"); >+assert(-Infinity >= BigInt("-1"), false, "-Infinity >= -1n"); >+assert(0n >= NaN, false, "0n >= NaN"); >+assert(NaN >= 0n, false, "NaN >= 0n"); >+ >+// BigInt - Boolean >+ >+assert(false >= 1n, false, "false >= 1n"); >+assert(1n >= false, true, "1n >= false"); >+assert(false >= 0n, true, "false >= 0n"); >+assert(0n >= false, true, "0n >= false"); >+assert(true >= 1n, true, "true >= 1n"); >+assert(1n >= true, true, "1n >= true"); >+assert(true >= 2n, false, "true >= 2n"); >+assert(2n >= true, true, "2n >= true"); >+ >+// BigInt - Symbol >+ >+try { >+ 1n >= Symbol("1"); >+ assert(false, true, "Comparison with Symbol shoud throw TypeError, but executed without exception"); >+} catch(e) { >+ assert(e instanceof TypeError, true, "Comparison with Symbol shoud throw TypeError, but throwed something else"); >+} >+ >diff --git a/JSTests/stress/big-int-less-than-or-equal-general.js b/JSTests/stress/big-int-less-than-or-equal-general.js >new file mode 100644 >index 0000000..44ffa57 >--- /dev/null >+++ b/JSTests/stress/big-int-less-than-or-equal-general.js >@@ -0,0 +1,148 @@ >+//@ runBigIntEnabled >+ >+// Copyright (C) 2017 Josh Wolfe. All rights reserved. >+// Copyright (C) 2017 Robin Templeton. All rights reserved. >+// Copyright (C) 2018 Igalia, S.L. All rights reserved. >+// This code is governed by the BSD license found in the LICENSE file. >+ >+function assert(v, e, m) { >+ if (v !== e) >+ throw new Error(m); >+} >+ >+assert(0n <= 0n, true, "0n <= 0n"); >+assert(1n <= 1n, true, "1n <= 1n"); >+assert(BigInt("-1") <= BigInt("-1"), true, "-1n <= -1n"); >+assert(0n <= BigInt("-0"), true, "0n <= -0n"); >+assert(BigInt("-0") <= 0n, true, "-0n <= 0n"); >+assert(0n <= 1n, true, "0n <= 1n"); >+assert(1n <= 0n, false, "1n <= 0n"); >+assert(0n <= BigInt("-1"), false, "0n <= -1n"); >+assert(BigInt("-1") <= 0n, true, "-1n <= 0n"); >+assert(1n <= BigInt("-1"), false, "1n <= -1n"); >+assert(BigInt("-1") <= 1n, true, "-1n <= 1n"); >+assert(0x1fffffffffffff01n <= 0x1fffffffffffff02n, true, "0x1fffffffffffff01n <= 0x1fffffffffffff02n"); >+assert(0x1fffffffffffff02n <= 0x1fffffffffffff01n, false, "0x1fffffffffffff02n <= 0x1fffffffffffff01n"); >+assert(BigInt("-2305843009213693697") <= BigInt("-2305843009213693698"), false, "-2305843009213693697n <= -2305843009213693698n"); >+assert(BigInt("-2305843009213693698") <= BigInt("-2305843009213693697"), true, "-2305843009213693698n <= -2305843009213693697n"); >+assert(0x10000000000000000n <= 0n, false, "0x10000000000000000n <= 0n"); >+assert(0n <= 0x10000000000000000n, true, "0n <= 0x10000000000000000n"); >+assert(0x10000000000000000n <= 1n, false, "0x10000000000000000n <= 1n"); >+assert(1n <= 0x10000000000000000n, true, "1n <= 0x10000000000000000n"); >+assert(0x10000000000000000n <= BigInt("-1"), false, "0x10000000000000000n <= -1n"); >+assert(BigInt("-1") <= 0x10000000000000000n, true, "-1n <= 0x10000000000000000n"); >+assert(0x10000000000000001n <= 0n, false, "0x10000000000000001n <= 0n"); >+assert(0n <= 0x10000000000000001n, true, "0n <= 0x10000000000000001n"); >+assert(BigInt("-18446744073709551616") <= 0n, true, "-18446744073709551616n <= 0n"); >+assert(0n <= BigInt("-18446744073709551616"), false, "0n <= -18446744073709551616n"); >+assert(BigInt("-18446744073709551616") <= 1n, true, "-18446744073709551616n <= 1n"); >+assert(1n <= BigInt("-18446744073709551616"), false, "1n <= -18446744073709551616n"); >+assert(BigInt("-18446744073709551616") <= BigInt("-1"), true, "-18446744073709551616n <= -1n"); >+assert(BigInt("-1") <= BigInt("-18446744073709551616"), false, "-1n <= -18446744073709551616n"); >+assert(BigInt("-18446744073709551617") <= 0n, true, "-18446744073709551617n <= 0n"); >+assert(0n <= BigInt("-18446744073709551617"), false, "0n <= -18446744073709551617n"); >+assert(0x10000000000000000n <= 0x100000000n, false, "0x10000000000000000n <= 0x100000000n"); >+assert(0x100000000n <= 0x10000000000000000n, true, "0x100000000n <= 0x10000000000000000n"); >+ >+// BigInt - String >+ >+assert(0n <= "0", true, "0n <= '0'"); >+assert("0" <= 0n, true, "'0' <= 0n"); >+assert(0n <= "1", true, "0n <= '1'"); >+assert("0" <= 1n, true, "'0' <= 1n"); >+assert(1n <= "0", false, "1n <= '0'"); >+assert("1" <= 0n, false, "'1' <= 0n"); >+assert(0n <= "", true, "0n <= ''"); >+assert("" <= 0n, true, "'' <= 0n"); >+assert(0n <= "1", true, "0n <= '1'"); >+assert("" <= 1n, true, "'' <= 1n"); >+assert(1n <= "", false, "1n <= ''"); >+assert("1" <= 0n, false, "'1' <= 0n"); >+assert(1n <= "1", true, "1n <= '1'"); >+assert("1" <= 1n, true, "'1' <= 1n"); >+assert(1n <= "-1", false, "1n <= '-1'"); >+assert("1" <= BigInt("-1"), false, "'1' <= -1n"); >+assert(BigInt("-1") <= "1", true, "-1n <= '1'"); >+assert("-1" <= 1n, true, "'-1' <= 1n"); >+assert(BigInt("-1") <= "-1", true, "-1n <= '-1'"); >+assert("-1" <= BigInt("-1"), true, "'-1' <= -1n"); >+assert(9007199254740993n <= "9007199254740992", false, "9007199254740993n <= '9007199254740992'"); >+assert("9007199254740993" <= 9007199254740992n, false, "'9007199254740993' <= 9007199254740992n"); >+assert(BigInt("-9007199254740992") <= "-9007199254740993", false, "-9007199254740992n <= '-9007199254740993'"); >+assert("-9007199254740992" <= BigInt("-9007199254740993"), false, "'-9007199254740992' <= -9007199254740993n"); >+assert("0x10" <= 3n, false, "'0x10' <= 3n"); >+assert("0x10" <= 2n, false, "'0x10' <= 2n"); >+assert("0x10" <= 1n, false, "'0x10' <= 1n"); >+assert("0o10" <= 7n, false, "'0o10' <= 7n"); >+assert("0o10" <= 8n, true, "'0o10' <= 8n"); >+assert("0o10" <= 9n, true, "'0o10' <= 9n"); >+assert("0b10" <= 3n, true, "'0b10' <= 3n"); >+assert("0b10" <= 2n, true, "'0b10' <= 2n"); >+assert("0b10" <= 1n, false, "'0b10' <= 1n"); >+ >+// Invalid String >+ >+assert("b10" <= 2n, false, "'b10' > 2n"); >+assert("bbb10" <= 2n, false, "'bbb10' > 2n"); >+ >+// BigInt - Number >+ >+assert(0n <= 0, true, "0n <= 0"); >+assert(0 <= 0n, true, "0 <= 0n"); >+assert(0n <= -0, true, "0n <= -0"); >+assert(-0 <= 0n, true, "-0 <= 0n"); >+assert(0n <= 0.000000000001, true, "0n <= 0.000000000001"); >+assert(0.000000000001 <= 0n, false, "0.000000000001 <= 0n"); >+assert(0n <= 1, true, "0n <= 1"); >+assert(1 <= 0n, false, "1 <= 0n"); >+assert(1n <= 0, false, "1n <= 0"); >+assert(0 <= 1n, true, "0 <= 1n"); >+assert(1n <= 0.999999999999, false, "1n <= 0.999999999999"); >+assert(0.999999999999 <= 1n, true, "0.999999999999 <= 1n"); >+assert(1n <= 1, true, "1n <= 1"); >+assert(1 <= 1n, true, "1 <= 1n"); >+assert(0n <= Number.MIN_VALUE, true, "0n <= Number.MIN_VALUE"); >+assert(Number.MIN_VALUE <= 0n, false, "Number.MIN_VALUE <= 0n"); >+assert(0n <= -Number.MIN_VALUE, false, "0n <= -Number.MIN_VALUE"); >+assert(-Number.MIN_VALUE <= 0n, true, "-Number.MIN_VALUE <= 0n"); >+assert(BigInt("-10") <= Number.MIN_VALUE, true, "-10n <= Number.MIN_VALUE"); >+assert(Number.MIN_VALUE <= BigInt("-10"), false, "Number.MIN_VALUE <= -10n"); >+assert(1n <= Number.MAX_VALUE, true, "1n <= Number.MAX_VALUE"); >+assert(Number.MAX_VALUE <= 1n, false, "Number.MAX_VALUE <= 1n"); >+assert(1n <= -Number.MAX_VALUE, false, "1n <= -Number.MAX_VALUE"); >+assert(-Number.MAX_VALUE <= 1n, true, "-Number.MAX_VALUE <= 1n"); >+assert(0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn <= Number.MAX_VALUE, true, "0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn <= Number.MAX_VALUE"); >+assert(Number.MAX_VALUE <= 0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn, false, "Number.MAX_VALUE <= 0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn"); >+assert(0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n <= Number.MAX_VALUE, false, "0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n <= Number.MAX_VALUE"); >+assert(Number.MAX_VALUE <= 0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n, true, "Number.MAX_VALUE <= 0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n"); >+assert(1n <= Infinity, true, "1n <= Infinity"); >+assert(Infinity <= 1n, false, "Infinity <= 1n"); >+assert(BigInt("-1") <= Infinity, true, "-1n <= Infinity"); >+assert(Infinity <= BigInt("-1"), false, "Infinity <= -1n"); >+assert(1n <= -Infinity, false, "1n <= -Infinity"); >+assert(-Infinity <= 1n, true, "-Infinity <= 1n"); >+assert(BigInt("-1") <= -Infinity, false, "-1n <= -Infinity"); >+assert(-Infinity <= BigInt("-1"), true, "-Infinity <= -1n"); >+assert(0n <= NaN, false, "0n <= NaN"); >+assert(NaN <= 0n, false, "NaN <= 0n"); >+ >+// BigInt - Boolean >+ >+assert(false <= 1n, true, "false <= 1n"); >+assert(1n <= false, false, "1n <= false"); >+assert(false <= 0n, true, "false <= 0n"); >+assert(0n <= false, true, "0n <= false"); >+assert(true <= 1n, true, "true <= 1n"); >+assert(1n <= true, true, "1n <= true"); >+assert(true <= 2n, true, "true <= 2n"); >+assert(2n <= true, false, "2n <= true"); >+ >+// BigInt - Symbol >+ >+try { >+ 1n <= Symbol("1"); >+ assert(false, true, "Comparison with Symbol shoud throw TypeError, but executed without exception"); >+} catch(e) { >+ assert(e instanceof TypeError, true, "Comparison with Symbol shoud throw TypeError, but throwed something else"); >+} >+ >diff --git a/JSTests/stress/big-int-less-than-or-equal-jit.js b/JSTests/stress/big-int-less-than-or-equal-jit.js >new file mode 100644 >index 0000000..f356844 >--- /dev/null >+++ b/JSTests/stress/big-int-less-than-or-equal-jit.js >@@ -0,0 +1,24 @@ >+//@ runBigIntEnabled >+ >+function assert(a) { >+ if (!a) >+ throw new Error("Bad assertion"); >+} >+ >+function lessThanOrEqualTest(a, b) { >+ return a <= b; >+} >+noInline(lessThanOrEqualTest); >+ >+for (let i = 0; i < 100000; i++) { >+ assert(lessThanOrEqualTest(3n, 4) === true); >+} >+ >+for (let i = 0; i < 100000; i++) { >+ assert(lessThanOrEqualTest(3n, 4n) === true); >+} >+ >+for (let i = 0; i < 100000; i++) { >+ assert(lessThanOrEqualTest(3n, "4") === true); >+} >+ >diff --git a/JSTests/stress/big-int-less-than-or-equal-order-of-evaluation.js b/JSTests/stress/big-int-less-than-or-equal-order-of-evaluation.js >new file mode 100644 >index 0000000..64ea754 >--- /dev/null >+++ b/JSTests/stress/big-int-less-than-or-equal-order-of-evaluation.js >@@ -0,0 +1,55 @@ >+//@ runBigIntEnabled >+ >+function assert(v, e, m) { >+ if (v !== e) >+ throw new Error(m); >+} >+ >+let o = { >+ [Symbol.toPrimitive]: function() { >+ throw new Error("Calling @toPrimitive"); >+ } >+} >+ >+try { >+ o <= Symbol(2); >+ assert(true, false, "") >+} catch(e) { >+ assert(e.message, "Calling @toPrimitive", "Bad Exception when object is left operand"); >+} >+ >+try { >+ Symbol(2) <= o; >+ assert(true, false, "") >+} catch(e) { >+ assert(e instanceof TypeError, true, "Bad Exception when Symbol is left operand"); >+} >+ >+o = { >+ [Symbol.toPrimitive]: function() { >+ return 2n; >+ }, >+ >+ toString: function() { >+ throw new Error("Should never call toString"); >+ }, >+ >+ valueOf: function() { >+ throw new Error("Should never call valueOf"); >+ } >+} >+ >+assert(o <= 3n, true, "ToPrimitive(2n) <= 3n"); >+ >+o = { >+ toString: function() { >+ throw new Error("Should never call toString"); >+ }, >+ >+ valueOf: function() { >+ return 2n; >+ } >+} >+ >+assert(o <= 3n, true, "valueOf(2n) <= 3n"); >+ >diff --git a/JSTests/stress/big-int-less-than-or-equal-wrapped-values.js b/JSTests/stress/big-int-less-than-or-equal-wrapped-values.js >new file mode 100644 >index 0000000..237c56a >--- /dev/null >+++ b/JSTests/stress/big-int-less-than-or-equal-wrapped-values.js >@@ -0,0 +1,63 @@ >+//@ runBigIntEnabled >+ >+function assert(v, e, m) { >+ if (v !== e) >+ throw new Error(m); >+} >+ >+assert(Object(2n) <= 1n, false, "Object(2n) <= 1n"); >+assert(1n <= Object(2n), true, "1n <= Object(2n)"); >+assert(Object(2n) <= Object(1n), false, "Object(2n) <= Object(1n)"); >+assert(Object(1n) <= Object(2n), true, "Object(1n) <= Object(2n)"); >+ >+let o = { >+ [Symbol.toPrimitive]: function() { >+ return 2n; >+ } >+} >+ >+let o2 = { >+ [Symbol.toPrimitive]: function() { >+ return 1n; >+ } >+} >+ >+assert(o <= 1n, false, "ToPrimitive(2n) <= 1n"); >+assert(1n <= o, true, "1n <= ToPrimitive(2n)"); >+assert(o <= o2, false, "ToPrimitive(2n) <= ToPrimitive(1n)"); >+assert(o2 <= o, true, "ToPrimitive(1n) <= ToPrimitive(2n)"); >+ >+o = { >+ valueOf: function() { >+ return 2n; >+ } >+} >+ >+o2 = { >+ valueOf: function() { >+ return 1n; >+ } >+} >+ >+assert(o <= 1n, false, "ToPrimitive(2n) <= 1n"); >+assert(1n <= o, true, "1n <= ToPrimitive(2n)"); >+assert(o <= o2, false, "ToPrimitive(2n) <= ToPrimitive(1n)"); >+assert(o2 <= o, true, "ToPrimitive(1n) <= ToPrimitive(2n)"); >+ >+o = { >+ toString: function() { >+ return 2n; >+ } >+} >+ >+o2 = { >+ toString: function() { >+ return 1n; >+ } >+} >+ >+assert(o <= 1n, false, "ToPrimitive(2n) <= 1n"); >+assert(1n <= o, true, "1n <= ToPrimitive(2n)"); >+assert(o <= o2, false, "ToPrimitive(2n) <= ToPrimitive(1n)"); >+assert(o2 <= o, true, "ToPrimitive(1n) <= ToPrimitive(2n)"); >+ >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 2873e04..5741ede 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,23 @@ >+2018-05-30 Caio Lima <ticaiolima@gmail.com> >+ >+ [ESNext][BigInt] Implement support for "=<" and ">=" relational operation >+ https://bugs.webkit.org/show_bug.cgi?id=185929 >+ >+ Reviewed by Yusuke Suzuki. >+ >+ This patch is introducing support to BigInt operands into ">=" and >+ "<=" operators. >+ Here we introduce ```bigIntCompareResult``` that is a helper function >+ to reuse code between "less than" and "less than or equal" operators. >+ >+ * runtime/JSBigInt.h: >+ * runtime/Operations.h: >+ (JSC::bigIntCompareResult): >+ (JSC::bigIntCompare): >+ (JSC::jsLess): >+ (JSC::jsLessEq): >+ (JSC::bigIntCompareLess): Deleted. >+ > 2018-05-30 Daniel Bates <dabates@apple.com> > > Web Inspector: Annotate Same-Site cookies >diff --git a/Source/JavaScriptCore/runtime/JSBigInt.h b/Source/JavaScriptCore/runtime/JSBigInt.h >index 28e24aa..28e4da6 100644 >--- a/Source/JavaScriptCore/runtime/JSBigInt.h >+++ b/Source/JavaScriptCore/runtime/JSBigInt.h >@@ -87,6 +87,11 @@ public: > std::optional<uint8_t> singleDigitValueForString(); > String toString(ExecState*, unsigned radix); > >+ enum class ComparisonMode { >+ LessThan, >+ LessThanOrEqual >+ }; >+ > enum class ComparisonResult { > Equal, > Undefined, >diff --git a/Source/JavaScriptCore/runtime/Operations.h b/Source/JavaScriptCore/runtime/Operations.h >index 9a97ba9..3967150 100644 >--- a/Source/JavaScriptCore/runtime/Operations.h >+++ b/Source/JavaScriptCore/runtime/Operations.h >@@ -157,7 +157,16 @@ ALWAYS_INLINE JSValue jsStringFromArguments(ExecState* exec, JSValue thisValue) > return ropeBuilder.release(); > } > >-ALWAYS_INLINE bool bigIntCompareLess(CallFrame* callFrame, JSValue v1, JSValue v2) >+ALWAYS_INLINE bool bigIntCompareResult(JSBigInt::ComparisonResult comparisonResult, JSBigInt::ComparisonMode comparisonMode) >+{ >+ if (comparisonMode == JSBigInt::ComparisonMode::LessThan) >+ return comparisonResult == JSBigInt::ComparisonResult::LessThan; >+ >+ ASSERT(comparisonMode == JSBigInt::ComparisonMode::LessThanOrEqual); >+ return comparisonResult == JSBigInt::ComparisonResult::LessThan || comparisonResult == JSBigInt::ComparisonResult::Equal; >+} >+ >+ALWAYS_INLINE bool bigIntCompare(CallFrame* callFrame, JSValue v1, JSValue v2, JSBigInt::ComparisonMode comparisonMode) > { > ASSERT(v1.isBigInt() || v2.isBigInt()); > ASSERT(v1.isPrimitive() && v2.isPrimitive()); >@@ -166,7 +175,7 @@ ALWAYS_INLINE bool bigIntCompareLess(CallFrame* callFrame, JSValue v1, JSValue v > auto scope = DECLARE_THROW_SCOPE(vm); > > if (v1.isBigInt() && v2.isBigInt()) >- return JSBigInt::compare(asBigInt(v1), asBigInt(v2)) == JSBigInt::ComparisonResult::LessThan; >+ return bigIntCompareResult(JSBigInt::compare(asBigInt(v1), asBigInt(v2)), comparisonMode); > > if (v1.isBigInt()) { > JSValue primValue = v2; >@@ -176,15 +185,15 @@ ALWAYS_INLINE bool bigIntCompareLess(CallFrame* callFrame, JSValue v1, JSValue v > if (!bigIntValue) > return false; > >- return JSBigInt::compare(asBigInt(v1), bigIntValue) == JSBigInt::ComparisonResult::LessThan; >+ return bigIntCompareResult(JSBigInt::compare(asBigInt(v1), bigIntValue), comparisonMode); > } > > if (primValue.isBigInt()) >- return JSBigInt::compare(asBigInt(v1), asBigInt(primValue)) == JSBigInt::ComparisonResult::LessThan; >+ return bigIntCompareResult(JSBigInt::compare(asBigInt(v1), asBigInt(primValue)), comparisonMode); > > double numberValue = primValue.toNumber(callFrame); > RETURN_IF_EXCEPTION(scope, false); >- return JSBigInt::compareToDouble(asBigInt(v1), numberValue) == JSBigInt::ComparisonResult::LessThan; >+ return bigIntCompareResult(JSBigInt::compareToDouble(asBigInt(v1), numberValue), comparisonMode); > } > > JSValue primValue = v1; >@@ -194,15 +203,21 @@ ALWAYS_INLINE bool bigIntCompareLess(CallFrame* callFrame, JSValue v1, JSValue v > if (!bigIntValue) > return false; > >- return JSBigInt::compare(bigIntValue, asBigInt(v2)) == JSBigInt::ComparisonResult::LessThan; >+ return bigIntCompareResult(JSBigInt::compare(bigIntValue, asBigInt(v2)), comparisonMode); > } > > if (primValue.isBigInt()) >- return JSBigInt::compare(asBigInt(primValue), asBigInt(v2)) == JSBigInt::ComparisonResult::LessThan; >+ return bigIntCompareResult(JSBigInt::compare(asBigInt(primValue), asBigInt(v2)), comparisonMode); > > double numberValue = primValue.toNumber(callFrame); > RETURN_IF_EXCEPTION(scope, false); >- return JSBigInt::compareToDouble(asBigInt(v2), numberValue) == JSBigInt::ComparisonResult::GreaterThan; >+ >+ // Here we check inverted because BigInt is the v2 >+ JSBigInt::ComparisonResult comparisonResult = JSBigInt::compareToDouble(asBigInt(v2), numberValue); >+ if (comparisonMode == JSBigInt::ComparisonMode::LessThan) >+ return comparisonResult == JSBigInt::ComparisonResult::GreaterThan; >+ >+ return comparisonResult == JSBigInt::ComparisonResult::GreaterThan || comparisonResult == JSBigInt::ComparisonResult::Equal; > } > > ALWAYS_INLINE bool toPrimitiveNumeric(CallFrame* callFrame, JSValue v, JSValue& p, double& n) >@@ -258,11 +273,12 @@ ALWAYS_INLINE bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2) > if (wasNotString1 | wasNotString2) { > if (p1.isBigInt() || p2.isBigInt()) { > scope.release(); >- return bigIntCompareLess(callFrame, p1, p2); >+ return bigIntCompare(callFrame, p1, p2, JSBigInt::ComparisonMode::LessThan); > } > > return n1 < n2; > } >+ > return codePointCompareLessThan(asString(p1)->value(callFrame), asString(p2)->value(callFrame)); > } > >@@ -291,18 +307,24 @@ ALWAYS_INLINE bool jsLessEq(CallFrame* callFrame, JSValue v1, JSValue v2) > bool wasNotString1; > bool wasNotString2; > if (leftFirst) { >- wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1); >+ wasNotString1 = toPrimitiveNumeric(callFrame, v1, p1, n1); > RETURN_IF_EXCEPTION(scope, false); >- wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2); >+ wasNotString2 = toPrimitiveNumeric(callFrame, v2, p2, n2); > } else { >- wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2); >+ wasNotString2 = toPrimitiveNumeric(callFrame, v2, p2, n2); > RETURN_IF_EXCEPTION(scope, false); >- wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1); >+ wasNotString1 = toPrimitiveNumeric(callFrame, v1, p1, n1); > } > RETURN_IF_EXCEPTION(scope, false); > >- if (wasNotString1 | wasNotString2) >+ if (wasNotString1 | wasNotString2) { >+ if (p1.isBigInt() || p2.isBigInt()) { >+ scope.release(); >+ return bigIntCompare(callFrame, p1, p2, JSBigInt::ComparisonMode::LessThanOrEqual); >+ } >+ > return n1 <= n2; >+ } > return !codePointCompareLessThan(asString(p2)->value(callFrame), asString(p1)->value(callFrame)); > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 185929
:
341243
|
341638
| 341722