WebKit Bugzilla
Attachment 341815 Details for
Bug 179002
: [ESNext][BigInt] Implement support for addition operations
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for landing
big-int-addition.diff (text/plain), 69.52 KB, created by
Caio Lima
on 2018-06-01 19:22:03 PDT
(
hide
)
Description:
Patch for landing
Filename:
MIME Type:
Creator:
Caio Lima
Created:
2018-06-01 19:22:03 PDT
Size:
69.52 KB
patch
obsolete
>diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog >index e37f8db..601cf08 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,27 @@ >+2018-06-01 Caio Lima <ticaiolima@gmail.com> >+ >+ [ESNext][BigInt] Implement support for addition operations >+ https://bugs.webkit.org/show_bug.cgi?id=179002 >+ >+ Reviewed by Yusuke Suzuki. >+ >+ * bigIntTests.yaml: >+ * stress/addition-order-evaluation.js: Added. >+ * stress/big-int-add-wrapped-value.js: Added. >+ * stress/big-int-addition-basic.js: Added. >+ * stress/big-int-addition-jit.js: Added. >+ * stress/big-int-addition-memory-stress.js: Added. >+ * stress/big-int-addition-string-coercion.js: Added. >+ * stress/big-int-addition-to-primitive-precedence.js: Added. >+ * stress/big-int-addition-to-primitive.js: Added. >+ * stress/big-int-addition-type-error.js: Added. >+ * stress/big-int-no-conversion-to-number.js: >+ * stress/big-int-sub-wrapped-value.js: Added. >+ * stress/big-int-subtraction-basic.js: Added. >+ * stress/big-int-subtraction-jit.js: Added. >+ * stress/big-int-subtraction-type-error.js: Added. >+ * stress/sub-order-evaluation.js: Added. >+ > 2018-05-29 Yusuke Suzuki <utatane.tea@gmail.com> > > [JSC] Add Symbol.prototype.description getter >diff --git a/JSTests/bigIntTests.yaml b/JSTests/bigIntTests.yaml >index 756e49b..787834a 100644 >--- a/JSTests/bigIntTests.yaml >+++ b/JSTests/bigIntTests.yaml >@@ -187,3 +187,38 @@ > - path: stress/big-int-mod-jit.js > cmd: runBigIntEnabled > >+- path: stress/big-int-add-wrapped-value.js >+ cmd: runBigIntEnabled >+ >+- path: stress/big-int-addition-basic.js >+ cmd: runBigIntEnabled >+ >+- path: stress/big-int-addition-jit.js >+ cmd: runBigIntEnabled >+ >+- path: stress/big-int-addition-memory-stress.js >+ cmd: runBigIntEnabled >+ >+- path: stress/big-int-addition-string-coercion.js >+ cmd: runBigIntEnabled >+ >+- path: stress/big-int-addition-to-primitive-precedence.js >+ cmd: runBigIntEnabled >+ >+- path: stress/big-int-addition-to-primitive.js >+ cmd: runBigIntEnabled >+ >+- path: stress/big-int-addition-type-error.js >+ cmd: runBigIntEnabled >+ >+- path: stress/big-int-sub-wrapped-value.js >+ cmd: runBigIntEnabled >+ >+- path:stress/big-int-subtraction-basic.js >+ cmd: runBigIntEnabled >+ >+- path: stress/big-int-subtraction-jit.js >+ cmd: runBigIntEnabled >+ >+- path: stress/big-int-subtraction-type-error.js >+ cmd: runBigIntEnabled >diff --git a/JSTests/stress/addition-order-evaluation.js b/JSTests/stress/addition-order-evaluation.js >new file mode 100644 >index 0000000..d06f1aa >--- /dev/null >+++ b/JSTests/stress/addition-order-evaluation.js >@@ -0,0 +1,23 @@ >+function assert(a, message) { >+ if (!a) >+ throw new Error(message); >+} >+ >+let o = { >+ valueOf: function () { throw new Error("Oops"); } >+}; >+ >+try { >+ let n = Symbol("3") + o; >+ assert(false, message + ": Should throw Error, but executed without exception"); >+} catch (e) { >+ assert(e.message === "Oops","Expected Error('Oops'), got: " + e); >+} >+ >+try { >+ let n = o + Symbol("3"); >+ assert(false, message + ": Should throw Error, but executed without exception"); >+} catch (e) { >+ assert(e.message === "Oops","Expected Error('Oops'), got: " + e); >+} >+ >diff --git a/JSTests/stress/big-int-add-wrapped-value.js b/JSTests/stress/big-int-add-wrapped-value.js >new file mode 100644 >index 0000000..8a378bfb >--- /dev/null >+++ b/JSTests/stress/big-int-add-wrapped-value.js >@@ -0,0 +1,37 @@ >+//@ runBigIntEnabled >+ >+assert = { >+ sameValue: function (input, expected, message) { >+ if (input !== expected) >+ throw new Error(message); >+ } >+}; >+ >+function testAdd(x, y, z, message) { >+ assert.sameValue(x + y, z, message); >+ assert.sameValue(y + x, z, message); >+} >+ >+testAdd(Object(2n), 1n, 3n, "ToPrimitive: unbox object with internal slot"); >+ >+let o = { >+ [Symbol.toPrimitive]: function() { >+ return 2n; >+ } >+}; >+testAdd(o, 1n, 3n, "ToPrimitive: @@toPrimitive"); >+ >+o = { >+ valueOf: function() { >+ return 2n; >+ } >+}; >+testAdd(o, 1n, 3n, "ToPrimitive: valueOf"); >+ >+o = { >+ toString: function() { >+ return 2n; >+ } >+} >+testAdd(o, 1n, 3n, "ToPrimitive: toString"); >+ >diff --git a/JSTests/stress/big-int-addition-basic.js b/JSTests/stress/big-int-addition-basic.js >new file mode 100644 >index 0000000..9e57feb >--- /dev/null >+++ b/JSTests/stress/big-int-addition-basic.js >@@ -0,0 +1,169 @@ >+//@ runBigIntEnabled >+ >+assert = { >+ sameValue: function (input, expected, message) { >+ if (input !== expected) >+ throw new Error(message); >+ } >+}; >+ >+function testAdd(x, y, z) { >+ assert.sameValue(x + y, z, x + " + " + y + " = " + z); >+ assert.sameValue(y + x, z, y + " + " + x + " = " + z); >+} >+ >+testAdd(10n, 239n, 249n); >+testAdd(0xFEDCBA9876543210n, 0xFEDCBA9876543210n, 0x1FDB97530ECA86420n); >+testAdd(0xFEDCBA9876543210n, 0xFEDCBA987654320Fn, 0x1FDB97530ECA8641Fn); >+testAdd(0xFEDCBA9876543210n, 0xFEDCBA98n, 0xFEDCBA997530ECA8n); >+testAdd(0xFEDCBA9876543210n, 0xFEDCBA97n, 0xFEDCBA997530ECA7n); >+testAdd(0xFEDCBA9876543210n, 0x1234n, 0xFEDCBA9876544444n); >+testAdd(0xFEDCBA9876543210n, 0x3n, 0xFEDCBA9876543213n); >+testAdd(0xFEDCBA9876543210n, 0x2n, 0xFEDCBA9876543212n); >+testAdd(0xFEDCBA9876543210n, 0x1n, 0xFEDCBA9876543211n); >+testAdd(0xFEDCBA9876543210n, 0x0n, 0xFEDCBA9876543210n); >+testAdd(0xFEDCBA9876543210n, -0x1n, 0xFEDCBA987654320Fn); >+testAdd(0xFEDCBA9876543210n, -0x2n, 0xFEDCBA987654320En); >+testAdd(0xFEDCBA9876543210n, -0x3n, 0xFEDCBA987654320Dn); >+testAdd(0xFEDCBA9876543210n, -0x1234n, 0xFEDCBA9876541FDCn); >+testAdd(0xFEDCBA9876543210n, -0xFEDCBA97n, 0xFEDCBA9777777779n); >+testAdd(0xFEDCBA9876543210n, -0xFEDCBA98n, 0xFEDCBA9777777778n); >+testAdd(0xFEDCBA9876543210n, -0xFEDCBA987654320Fn, 0x1n); >+testAdd(0xFEDCBA9876543210n, -0xFEDCBA9876543210n, 0x0n); >+testAdd(0xFEDCBA987654320Fn, 0xFEDCBA987654320Fn, 0x1FDB97530ECA8641En); >+testAdd(0xFEDCBA987654320Fn, 0xFEDCBA98n, 0xFEDCBA997530ECA7n); >+testAdd(0xFEDCBA987654320Fn, 0xFEDCBA97n, 0xFEDCBA997530ECA6n); >+testAdd(0xFEDCBA987654320Fn, 0x1234n, 0xFEDCBA9876544443n); >+testAdd(0xFEDCBA987654320Fn, 0x3n, 0xFEDCBA9876543212n); >+testAdd(0xFEDCBA987654320Fn, 0x2n, 0xFEDCBA9876543211n); >+testAdd(0xFEDCBA987654320Fn, 0x1n, 0xFEDCBA9876543210n); >+testAdd(0xFEDCBA987654320Fn, 0x0n, 0xFEDCBA987654320Fn); >+testAdd(0xFEDCBA987654320Fn, -0x1n, 0xFEDCBA987654320En); >+testAdd(0xFEDCBA987654320Fn, -0x2n, 0xFEDCBA987654320Dn); >+testAdd(0xFEDCBA987654320Fn, -0x3n, 0xFEDCBA987654320Cn); >+testAdd(0xFEDCBA987654320Fn, -0x1234n, 0xFEDCBA9876541FDBn); >+testAdd(0xFEDCBA987654320Fn, -0xFEDCBA97n, 0xFEDCBA9777777778n); >+testAdd(0xFEDCBA987654320Fn, -0xFEDCBA98n, 0xFEDCBA9777777777n); >+testAdd(0xFEDCBA987654320Fn, -0xFEDCBA987654320Fn, 0x0n); >+testAdd(0xFEDCBA987654320Fn, -0xFEDCBA9876543210n, -0x1n); >+testAdd(0xFEDCBA98n, 0xFEDCBA98n, 0x1FDB97530n); >+testAdd(0xFEDCBA98n, 0xFEDCBA97n, 0x1FDB9752Fn); >+testAdd(0xFEDCBA98n, 0x1234n, 0xFEDCCCCCn); >+testAdd(0xFEDCBA98n, 0x3n, 0xFEDCBA9Bn); >+testAdd(0xFEDCBA98n, 0x2n, 0xFEDCBA9An); >+testAdd(0xFEDCBA98n, 0x1n, 0xFEDCBA99n); >+testAdd(0xFEDCBA98n, 0x0n, 0xFEDCBA98n); >+testAdd(0xFEDCBA98n, -0x1n, 0xFEDCBA97n); >+testAdd(0xFEDCBA98n, -0x2n, 0xFEDCBA96n); >+testAdd(0xFEDCBA98n, -0x3n, 0xFEDCBA95n); >+testAdd(0xFEDCBA98n, -0x1234n, 0xFEDCA864n); >+testAdd(0xFEDCBA98n, -0xFEDCBA97n, 0x1n); >+testAdd(0xFEDCBA98n, -0xFEDCBA98n, 0x0n); >+testAdd(0xFEDCBA98n, -0xFEDCBA987654320Fn, -0xFEDCBA9777777777n); >+testAdd(0xFEDCBA98n, -0xFEDCBA9876543210n, -0xFEDCBA9777777778n); >+testAdd(0xFEDCBA97n, 0xFEDCBA97n, 0x1FDB9752En); >+testAdd(0xFEDCBA97n, 0x1234n, 0xFEDCCCCBn); >+testAdd(0xFEDCBA97n, 0x3n, 0xFEDCBA9An); >+testAdd(0xFEDCBA97n, 0x2n, 0xFEDCBA99n); >+testAdd(0xFEDCBA97n, 0x1n, 0xFEDCBA98n); >+testAdd(0xFEDCBA97n, 0x0n, 0xFEDCBA97n); >+testAdd(0xFEDCBA97n, -0x1n, 0xFEDCBA96n); >+testAdd(0xFEDCBA97n, -0x2n, 0xFEDCBA95n); >+testAdd(0xFEDCBA97n, -0x3n, 0xFEDCBA94n); >+testAdd(0xFEDCBA97n, -0x1234n, 0xFEDCA863n); >+testAdd(0xFEDCBA97n, -0xFEDCBA97n, 0x0n); >+testAdd(0xFEDCBA97n, -0xFEDCBA98n, -0x1n); >+testAdd(0xFEDCBA97n, -0xFEDCBA987654320Fn, -0xFEDCBA9777777778n); >+testAdd(0xFEDCBA97n, -0xFEDCBA9876543210n, -0xFEDCBA9777777779n); >+testAdd(0x1234n, 0x1234n, 0x2468n); >+testAdd(0x1234n, 0x3n, 0x1237n); >+testAdd(0x1234n, 0x2n, 0x1236n); >+testAdd(0x1234n, 0x1n, 0x1235n); >+testAdd(0x1234n, 0x0n, 0x1234n); >+testAdd(0x1234n, -0x1n, 0x1233n); >+testAdd(0x1234n, -0x2n, 0x1232n); >+testAdd(0x1234n, -0x3n, 0x1231n); >+testAdd(0x1234n, -0x1234n, 0x0n); >+testAdd(0x1234n, -0xFEDCBA97n, -0xFEDCA863n); >+testAdd(0x1234n, -0xFEDCBA98n, -0xFEDCA864n); >+testAdd(0x1234n, -0xFEDCBA987654320Fn, -0xFEDCBA9876541FDBn); >+testAdd(0x1234n, -0xFEDCBA9876543210n, -0xFEDCBA9876541FDCn); >+testAdd(0x3n, 0x3n, 0x6n); >+testAdd(0x3n, 0x2n, 0x5n); >+testAdd(0x3n, 0x1n, 0x4n); >+testAdd(0x3n, 0x0n, 0x3n); >+testAdd(0x3n, -0x1n, 0x2n); >+testAdd(0x3n, -0x2n, 0x1n); >+testAdd(0x3n, -0x3n, 0x0n); >+testAdd(0x3n, -0x1234n, -0x1231n); >+testAdd(0x3n, -0xFEDCBA97n, -0xFEDCBA94n); >+testAdd(0x3n, -0xFEDCBA98n, -0xFEDCBA95n); >+testAdd(0x3n, -0xFEDCBA987654320Fn, -0xFEDCBA987654320Cn); >+testAdd(0x3n, -0xFEDCBA9876543210n, -0xFEDCBA987654320Dn); >+testAdd(0x2n, 0x2n, 0x4n); >+testAdd(0x2n, 0x1n, 0x3n); >+testAdd(0x2n, 0x0n, 0x2n); >+testAdd(0x2n, -0x1n, 0x1n); >+testAdd(0x2n, -0x2n, 0x0n); >+testAdd(0x2n, -0x3n, -0x1n); >+testAdd(0x2n, -0x1234n, -0x1232n); >+testAdd(0x2n, -0xFEDCBA97n, -0xFEDCBA95n); >+testAdd(0x2n, -0xFEDCBA98n, -0xFEDCBA96n); >+testAdd(0x2n, -0xFEDCBA987654320Fn, -0xFEDCBA987654320Dn); >+testAdd(0x2n, -0xFEDCBA9876543210n, -0xFEDCBA987654320En); >+testAdd(0x1n, 0x1n, 0x2n); >+testAdd(0x1n, 0x0n, 0x1n); >+testAdd(0x1n, -0x1n, 0x0n); >+testAdd(0x1n, -0x2n, -0x1n); >+testAdd(0x1n, -0x3n, -0x2n); >+testAdd(0x1n, -0x1234n, -0x1233n); >+testAdd(0x1n, -0xFEDCBA97n, -0xFEDCBA96n); >+testAdd(0x1n, -0xFEDCBA98n, -0xFEDCBA97n); >+testAdd(0x1n, -0xFEDCBA987654320Fn, -0xFEDCBA987654320En); >+testAdd(0x1n, -0xFEDCBA9876543210n, -0xFEDCBA987654320Fn); >+testAdd(0x0n, 0x0n, 0x0n); >+testAdd(0x0n, -0x1n, -0x1n); >+testAdd(0x0n, -0x2n, -0x2n); >+testAdd(0x0n, -0x3n, -0x3n); >+testAdd(0x0n, -0x1234n, -0x1234n); >+testAdd(0x0n, -0xFEDCBA97n, -0xFEDCBA97n); >+testAdd(0x0n, -0xFEDCBA98n, -0xFEDCBA98n); >+testAdd(0x0n, -0xFEDCBA987654320Fn, -0xFEDCBA987654320Fn); >+testAdd(0x0n, -0xFEDCBA9876543210n, -0xFEDCBA9876543210n); >+testAdd(-0x1n, -0x1n, -0x2n); >+testAdd(-0x1n, -0x2n, -0x3n); >+testAdd(-0x1n, -0x3n, -0x4n); >+testAdd(-0x1n, -0x1234n, -0x1235n); >+testAdd(-0x1n, -0xFEDCBA97n, -0xFEDCBA98n); >+testAdd(-0x1n, -0xFEDCBA98n, -0xFEDCBA99n); >+testAdd(-0x1n, -0xFEDCBA987654320Fn, -0xFEDCBA9876543210n); >+testAdd(-0x1n, -0xFEDCBA9876543210n, -0xFEDCBA9876543211n); >+testAdd(-0x2n, -0x2n, -0x4n); >+testAdd(-0x2n, -0x3n, -0x5n); >+testAdd(-0x2n, -0x1234n, -0x1236n); >+testAdd(-0x2n, -0xFEDCBA97n, -0xFEDCBA99n); >+testAdd(-0x2n, -0xFEDCBA98n, -0xFEDCBA9An); >+testAdd(-0x2n, -0xFEDCBA987654320Fn, -0xFEDCBA9876543211n); >+testAdd(-0x2n, -0xFEDCBA9876543210n, -0xFEDCBA9876543212n); >+testAdd(-0x3n, -0x3n, -0x6n); >+testAdd(-0x3n, -0x1234n, -0x1237n); >+testAdd(-0x3n, -0xFEDCBA97n, -0xFEDCBA9An); >+testAdd(-0x3n, -0xFEDCBA98n, -0xFEDCBA9Bn); >+testAdd(-0x3n, -0xFEDCBA987654320Fn, -0xFEDCBA9876543212n); >+testAdd(-0x3n, -0xFEDCBA9876543210n, -0xFEDCBA9876543213n); >+testAdd(-0x1234n, -0x1234n, -0x2468n); >+testAdd(-0x1234n, -0xFEDCBA97n, -0xFEDCCCCBn); >+testAdd(-0x1234n, -0xFEDCBA98n, -0xFEDCCCCCn); >+testAdd(-0x1234n, -0xFEDCBA987654320Fn, -0xFEDCBA9876544443n); >+testAdd(-0x1234n, -0xFEDCBA9876543210n, -0xFEDCBA9876544444n); >+testAdd(-0xFEDCBA97n, -0xFEDCBA97n, -0x1FDB9752En); >+testAdd(-0xFEDCBA97n, -0xFEDCBA98n, -0x1FDB9752Fn); >+testAdd(-0xFEDCBA97n, -0xFEDCBA987654320Fn, -0xFEDCBA997530ECA6n); >+testAdd(-0xFEDCBA97n, -0xFEDCBA9876543210n, -0xFEDCBA997530ECA7n); >+testAdd(-0xFEDCBA98n, -0xFEDCBA98n, -0x1FDB97530n); >+testAdd(-0xFEDCBA98n, -0xFEDCBA987654320Fn, -0xFEDCBA997530ECA7n); >+testAdd(-0xFEDCBA98n, -0xFEDCBA9876543210n, -0xFEDCBA997530ECA8n); >+testAdd(-0xFEDCBA987654320Fn, -0xFEDCBA987654320Fn, -0x1FDB97530ECA8641En); >+testAdd(-0xFEDCBA987654320Fn, -0xFEDCBA9876543210n, -0x1FDB97530ECA8641Fn); >+testAdd(-0xFEDCBA9876543210n, -0xFEDCBA9876543210n, -0x1FDB97530ECA86420n); >+ >diff --git a/JSTests/stress/big-int-addition-jit.js b/JSTests/stress/big-int-addition-jit.js >new file mode 100644 >index 0000000..1158e0a >--- /dev/null >+++ b/JSTests/stress/big-int-addition-jit.js >@@ -0,0 +1,19 @@ >+//@ runBigIntEnabled >+ >+let assert = { >+ sameValue: function(i, e, m) { >+ if (i !== e) >+ throw new Error(m); >+ } >+} >+ >+function bigIntAddition(x, y) { >+ return x + y; >+} >+noInline(bigIntAddition); >+ >+for (let i = 0; i < 10000; i++) { >+ let r = bigIntAddition(3n, 10n); >+ assert.sameValue(r, 13n, 3n + " + " + 10n + " = " + r); >+} >+ >diff --git a/JSTests/stress/big-int-addition-memory-stress.js b/JSTests/stress/big-int-addition-memory-stress.js >new file mode 100644 >index 0000000..8b1aeb1 >--- /dev/null >+++ b/JSTests/stress/big-int-addition-memory-stress.js >@@ -0,0 +1,14 @@ >+//@ runBigIntEnabled >+ >+function assert(a) { >+ if (!a) >+ throw new Error("Bad assertion"); >+} >+ >+let a = 0n; >+for (let i = 0; i < 1000000; i++) { >+ a += 30n; >+} >+ >+assert(a === 30000000n); >+ >diff --git a/JSTests/stress/big-int-addition-string-coercion.js b/JSTests/stress/big-int-addition-string-coercion.js >new file mode 100644 >index 0000000..bbde05a >--- /dev/null >+++ b/JSTests/stress/big-int-addition-string-coercion.js >@@ -0,0 +1,25 @@ >+//@ runBigIntEnabled >+ >+function assert(input, expected) { >+ if (input !== expected) >+ throw new Error("Bad!"); >+} >+ >+assert(-1n + "", "-1"); >+assert("" + -1n, "-1"); >+assert(0n + "", "0"); >+assert("" + 0n, "0"); >+assert(1n + "", "1"); >+assert("" + 1n, "1"); >+assert(123456789000000000000000n + "", "123456789000000000000000"); >+assert("" + 123456789000000000000000n, "123456789000000000000000"); >+assert(-123456789000000000000000n + "", "-123456789000000000000000"); >+assert("" + -123456789000000000000000n, "-123456789000000000000000"); >+ >+assert([] + -123456789000000000000000n, "-123456789000000000000000"); >+assert(-123456789000000000000000n + [], "-123456789000000000000000"); >+ >+let a = {}; >+assert(a + 3n, "[object Object]3"); >+assert(3n + a, "3[object Object]"); >+ >diff --git a/JSTests/stress/big-int-addition-to-primitive-precedence.js b/JSTests/stress/big-int-addition-to-primitive-precedence.js >new file mode 100644 >index 0000000..cdedc14 >--- /dev/null >+++ b/JSTests/stress/big-int-addition-to-primitive-precedence.js >@@ -0,0 +1,39 @@ >+//@ runBigIntEnabled >+ >+assert = { >+ sameValue: function (input, expected, message) { >+ if (input !== expected) >+ throw new Error(message); >+ } >+}; >+ >+function testAdd(x, y, z, message) { >+ assert.sameValue(x + y, z, message); >+ assert.sameValue(y + x, z, message); >+} >+ >+testAdd(Object(2n), 1n, 3n, "ToPrimitive: unbox object with internal slot"); >+ >+let o = { >+ [Symbol.toPrimitive]: function() { >+ return 2n; >+ }, >+ valueOf: function () { >+ throw new Error("Should never execute it"); >+ }, >+ toString: function () { >+ throw new Error("Should never execute it"); >+ } >+}; >+testAdd(o, 1n, 3n, "ToPrimitive: @@toPrimitive"); >+ >+o = { >+ valueOf: function() { >+ return 2n; >+ }, >+ toString: function () { >+ throw new Error("Should never execute it"); >+ } >+}; >+testAdd(o, 1n, 3n, "ToPrimitive: valueOf"); >+ >diff --git a/JSTests/stress/big-int-addition-to-primitive.js b/JSTests/stress/big-int-addition-to-primitive.js >new file mode 100644 >index 0000000..2f65f9c >--- /dev/null >+++ b/JSTests/stress/big-int-addition-to-primitive.js >@@ -0,0 +1,39 @@ >+//@ runBigIntEnabled >+ >+function assert(a) { >+ if (!a) >+ throw new Error("Bad assertion"); >+} >+ >+assert.sameValue = function (input, expected, message) { >+ if (input !== expected) >+ throw new Error(message); >+} >+ >+function testAdd(x, y, z) { >+ assert.sameValue(x + y, z, x + " + " + y + " = " + z); >+ assert.sameValue(y + x, z, y + " + " + x + " = " + z); >+} >+ >+let o = { >+ [Symbol.toPrimitive]: function () { return 300000000000000n; } >+} >+ >+testAdd(500000000000438n, o, 800000000000438n); >+ >+o.valueOf = function () { >+ throw new Error("Should never execute it"); >+}; >+ >+testAdd(700000000000438n, o, 1000000000000438n); >+ >+o.toString = function () { >+ throw new Error("Should never execute it"); >+}; >+ >+testAdd(700000000000438n, o, 1000000000000438n); >+ >+delete o.valueOf; >+ >+testAdd(700000000000438n, o, 1000000000000438n); >+ >diff --git a/JSTests/stress/big-int-addition-type-error.js b/JSTests/stress/big-int-addition-type-error.js >new file mode 100644 >index 0000000..e2f824c >--- /dev/null >+++ b/JSTests/stress/big-int-addition-type-error.js >@@ -0,0 +1,104 @@ >+//@ runBigIntEnabled >+ >+function assert(a, message) { >+ if (!a) >+ throw new Error(message); >+} >+ >+function assertThrowTypeError(a, b, message) { >+ try { >+ let n = a + b; >+ assert(false, message + ": Should throw TypeError, but executed without exception"); >+ } catch (e) { >+ assert(e instanceof TypeError, message + ": expected TypeError, got: " + e); >+ } >+} >+ >+assertThrowTypeError(30n, Symbol("foo"), "BigInt + Symbol"); >+assertThrowTypeError(Symbol("bar"), 18757382984821n, "Symbol + BigInt"); >+assertThrowTypeError(30n, 3320, "BigInt + Int32"); >+assertThrowTypeError(33256, 18757382984821n, "Int32 + BigInt"); >+assertThrowTypeError(30n, 0.543, "BigInt + Double"); >+assertThrowTypeError(230.19293, 18757382984821n, "Double + BigInt"); >+assertThrowTypeError(30n, NaN, "BigInt + NaN"); >+assertThrowTypeError(NaN, 18757382984821n, "NaN + BigInt"); >+assertThrowTypeError(30n, NaN, "BigInt + NaN"); >+assertThrowTypeError(NaN, 18757382984821n, "NaN + BigInt"); >+assertThrowTypeError(30n, +Infinity, "BigInt + NaN"); >+assertThrowTypeError(+Infinity, 18757382984821n, "NaN + BigInt"); >+assertThrowTypeError(30n, -Infinity, "BigInt + -Infinity"); >+assertThrowTypeError(-Infinity, 18757382984821n, "-Infinity + BigInt"); >+assertThrowTypeError(30n, null, "BigInt + null"); >+assertThrowTypeError(null, 18757382984821n, "null + BigInt"); >+assertThrowTypeError(30n, undefined, "BigInt + undefined"); >+assertThrowTypeError(undefined, 18757382984821n, "undefined + BigInt"); >+assertThrowTypeError(30n, true, "BigInt + true"); >+assertThrowTypeError(true, 18757382984821n, "true + BigInt"); >+assertThrowTypeError(30n, false, "BigInt + false"); >+assertThrowTypeError(false, 18757382984821n, "false + BigInt"); >+ >+// Error when returning from object >+ >+let o = { >+ valueOf: function () { return Symbol("Foo"); } >+}; >+ >+assertThrowTypeError(30n, o, "BigInt + Object.valueOf returning Symbol"); >+assertThrowTypeError(o, 18757382984821n, "Object.valueOf returning Symbol + BigInt"); >+ >+o = { >+ valueOf: function () { return 33256; } >+}; >+ >+assertThrowTypeError(30n, o, "BigInt + Object.valueOf returning Int32"); >+assertThrowTypeError(o, 18757382984821n, "Object.valueOf returning Int32 + BigInt"); >+ >+o = { >+ valueOf: function () { return 0.453; } >+}; >+ >+assertThrowTypeError(30n, o, "BigInt + Object.valueOf returning Double"); >+assertThrowTypeError(o, 18757382984821n, "Object.valueOf returning Double + BigInt"); >+ >+o = { >+ toString: function () { return Symbol("Foo"); } >+}; >+ >+assertThrowTypeError(30n, o, "BigInt + Object.toString returning Symbol"); >+assertThrowTypeError(o, 18757382984821n, "Object.toString returning Symbol + BigInt"); >+ >+o = { >+ toString: function () { return 33256; } >+}; >+ >+assertThrowTypeError(30n, o, "BigInt + Object.toString returning Int32"); >+assertThrowTypeError(o, 18757382984821n, "Object.toString returning Int32 + BigInt"); >+ >+o = { >+ toString: function () { return 0.453; } >+}; >+ >+assertThrowTypeError(30n, o, "BigInt + Object.toString returning Double"); >+assertThrowTypeError(o, 18757382984821n, "Object.toString returning Double + BigInt"); >+ >+o = { >+ [Symbol.toPrimitive]: function () { return Symbol("Foo"); } >+}; >+ >+assertThrowTypeError(30n, o, "BigInt + Object.@@toPrimitive returning Symbol"); >+assertThrowTypeError(o, 18757382984821n, "Object.@@toPrimitive returning Symbol + BigInt"); >+ >+o = { >+ [Symbol.toPrimitive]: function () { return 33256; } >+}; >+ >+assertThrowTypeError(30n, o, "BigInt + Object.@@toPrimitive returning Int32"); >+assertThrowTypeError(o, 18757382984821n, "Object.@@toPrimitive returning Int32 + BigInt"); >+ >+o = { >+ [Symbol.toPrimitive]: function () { return 0.453; } >+}; >+ >+assertThrowTypeError(30n, o, "BigInt + Object.@@toPrimitive returning Double"); >+assertThrowTypeError(o, 18757382984821n, "Object.@@toPrimitive returning Double + BigInt"); >+ >diff --git a/JSTests/stress/big-int-no-conversion-to-number.js b/JSTests/stress/big-int-no-conversion-to-number.js >index f380b57..1406128 100644 >--- a/JSTests/stress/big-int-no-conversion-to-number.js >+++ b/JSTests/stress/big-int-no-conversion-to-number.js >@@ -7,6 +7,6 @@ try { > message = error.message; > } > >-if (message !== "Conversion from 'BigInt' to 'number' is not allowed.") { >+if (message !== "Invalid mix of BigInt and other type in addition.") { > throw new Error("Error message has changed to something unexpected"); > } >diff --git a/JSTests/stress/big-int-sub-wrapped-value.js b/JSTests/stress/big-int-sub-wrapped-value.js >new file mode 100644 >index 0000000..5b18880 >--- /dev/null >+++ b/JSTests/stress/big-int-sub-wrapped-value.js >@@ -0,0 +1,36 @@ >+//@ runBigIntEnabled >+ >+assert = { >+ sameValue: function (input, expected, message) { >+ if (input !== expected) >+ throw new Error(message); >+ } >+}; >+ >+function testSub(x, y, z, message) { >+ assert.sameValue(x - y, z, message); >+} >+ >+testSub(Object(2n), 1n, 1n, "ToPrimitive: unbox object with internal slot"); >+ >+let o = { >+ [Symbol.toPrimitive]: function() { >+ return 2n; >+ } >+}; >+testSub(o, 1n, 1n, "ToPrimitive: @@toPrimitive"); >+ >+o = { >+ valueOf: function() { >+ return 2n; >+ } >+}; >+testSub(o, 1n, 1n, "ToPrimitive: valueOf"); >+ >+o = { >+ toString: function() { >+ return 2n; >+ } >+} >+testSub(o, 1n, 1n, "ToPrimitive: toString"); >+ >diff --git a/JSTests/stress/big-int-subtraction-basic.js b/JSTests/stress/big-int-subtraction-basic.js >new file mode 100644 >index 0000000..9021324 >--- /dev/null >+++ b/JSTests/stress/big-int-subtraction-basic.js >@@ -0,0 +1,303 @@ >+//@ runBigIntEnabled >+ >+assert = { >+ sameValue: function (input, expected, message) { >+ if (input !== expected) >+ throw new Error(message); >+ } >+}; >+ >+function testSub(x, y, z) { >+ assert.sameValue(x - y, z, x + " - " + y + " = " + z); >+} >+ >+testSub(0xFEDCBA9876543210n, 0xFEDCBA9876543210n, 0x0n); >+testSub(0xFEDCBA9876543210n, 0xFEDCBA987654320Fn, 0x1n); >+testSub(0xFEDCBA9876543210n, 0xFEDCBA98n, 0xFEDCBA9777777778n); >+testSub(0xFEDCBA9876543210n, 0xFEDCBA97n, 0xFEDCBA9777777779n); >+testSub(0xFEDCBA9876543210n, 0x1234n, 0xFEDCBA9876541FDCn); >+testSub(0xFEDCBA9876543210n, 0x3n, 0xFEDCBA987654320Dn); >+testSub(0xFEDCBA9876543210n, 0x2n, 0xFEDCBA987654320En); >+testSub(0xFEDCBA9876543210n, 0x1n, 0xFEDCBA987654320Fn); >+testSub(0xFEDCBA9876543210n, 0x0n, 0xFEDCBA9876543210n); >+testSub(0xFEDCBA9876543210n, -0x1n, 0xFEDCBA9876543211n); >+testSub(0xFEDCBA9876543210n, -0x2n, 0xFEDCBA9876543212n); >+testSub(0xFEDCBA9876543210n, -0x3n, 0xFEDCBA9876543213n); >+testSub(0xFEDCBA9876543210n, -0x1234n, 0xFEDCBA9876544444n); >+testSub(0xFEDCBA9876543210n, -0xFEDCBA97n, 0xFEDCBA997530ECA7n); >+testSub(0xFEDCBA9876543210n, -0xFEDCBA98n, 0xFEDCBA997530ECA8n); >+testSub(0xFEDCBA9876543210n, -0xFEDCBA987654320Fn, 0x1FDB97530ECA8641Fn); >+testSub(0xFEDCBA9876543210n, -0xFEDCBA9876543210n, 0x1FDB97530ECA86420n); >+testSub(0xFEDCBA987654320Fn, 0xFEDCBA9876543210n, -0x1n); >+testSub(0xFEDCBA987654320Fn, 0xFEDCBA987654320Fn, 0x0n); >+testSub(0xFEDCBA987654320Fn, 0xFEDCBA98n, 0xFEDCBA9777777777n); >+testSub(0xFEDCBA987654320Fn, 0xFEDCBA97n, 0xFEDCBA9777777778n); >+testSub(0xFEDCBA987654320Fn, 0x1234n, 0xFEDCBA9876541FDBn); >+testSub(0xFEDCBA987654320Fn, 0x3n, 0xFEDCBA987654320Cn); >+testSub(0xFEDCBA987654320Fn, 0x2n, 0xFEDCBA987654320Dn); >+testSub(0xFEDCBA987654320Fn, 0x1n, 0xFEDCBA987654320En); >+testSub(0xFEDCBA987654320Fn, 0x0n, 0xFEDCBA987654320Fn); >+testSub(0xFEDCBA987654320Fn, -0x1n, 0xFEDCBA9876543210n); >+testSub(0xFEDCBA987654320Fn, -0x2n, 0xFEDCBA9876543211n); >+testSub(0xFEDCBA987654320Fn, -0x3n, 0xFEDCBA9876543212n); >+testSub(0xFEDCBA987654320Fn, -0x1234n, 0xFEDCBA9876544443n); >+testSub(0xFEDCBA987654320Fn, -0xFEDCBA97n, 0xFEDCBA997530ECA6n); >+testSub(0xFEDCBA987654320Fn, -0xFEDCBA98n, 0xFEDCBA997530ECA7n); >+testSub(0xFEDCBA987654320Fn, -0xFEDCBA987654320Fn, 0x1FDB97530ECA8641En); >+testSub(0xFEDCBA987654320Fn, -0xFEDCBA9876543210n, 0x1FDB97530ECA8641Fn); >+testSub(0xFEDCBA98n, 0xFEDCBA9876543210n, -0xFEDCBA9777777778n); >+testSub(0xFEDCBA98n, 0xFEDCBA987654320Fn, -0xFEDCBA9777777777n); >+testSub(0xFEDCBA98n, 0xFEDCBA98n, 0x0n); >+testSub(0xFEDCBA98n, 0xFEDCBA97n, 0x1n); >+testSub(0xFEDCBA98n, 0x1234n, 0xFEDCA864n); >+testSub(0xFEDCBA98n, 0x3n, 0xFEDCBA95n); >+testSub(0xFEDCBA98n, 0x2n, 0xFEDCBA96n); >+testSub(0xFEDCBA98n, 0x1n, 0xFEDCBA97n); >+testSub(0xFEDCBA98n, 0x0n, 0xFEDCBA98n); >+testSub(0xFEDCBA98n, -0x1n, 0xFEDCBA99n); >+testSub(0xFEDCBA98n, -0x2n, 0xFEDCBA9An); >+testSub(0xFEDCBA98n, -0x3n, 0xFEDCBA9Bn); >+testSub(0xFEDCBA98n, -0x1234n, 0xFEDCCCCCn); >+testSub(0xFEDCBA98n, -0xFEDCBA97n, 0x1FDB9752Fn); >+testSub(0xFEDCBA98n, -0xFEDCBA98n, 0x1FDB97530n); >+testSub(0xFEDCBA98n, -0xFEDCBA987654320Fn, 0xFEDCBA997530ECA7n); >+testSub(0xFEDCBA98n, -0xFEDCBA9876543210n, 0xFEDCBA997530ECA8n); >+testSub(0xFEDCBA97n, 0xFEDCBA9876543210n, -0xFEDCBA9777777779n); >+testSub(0xFEDCBA97n, 0xFEDCBA987654320Fn, -0xFEDCBA9777777778n); >+testSub(0xFEDCBA97n, 0xFEDCBA98n, -0x1n); >+testSub(0xFEDCBA97n, 0xFEDCBA97n, 0x0n); >+testSub(0xFEDCBA97n, 0x1234n, 0xFEDCA863n); >+testSub(0xFEDCBA97n, 0x3n, 0xFEDCBA94n); >+testSub(0xFEDCBA97n, 0x2n, 0xFEDCBA95n); >+testSub(0xFEDCBA97n, 0x1n, 0xFEDCBA96n); >+testSub(0xFEDCBA97n, 0x0n, 0xFEDCBA97n); >+testSub(0xFEDCBA97n, -0x1n, 0xFEDCBA98n); >+testSub(0xFEDCBA97n, -0x2n, 0xFEDCBA99n); >+testSub(0xFEDCBA97n, -0x3n, 0xFEDCBA9An); >+testSub(0xFEDCBA97n, -0x1234n, 0xFEDCCCCBn); >+testSub(0xFEDCBA97n, -0xFEDCBA97n, 0x1FDB9752En); >+testSub(0xFEDCBA97n, -0xFEDCBA98n, 0x1FDB9752Fn); >+testSub(0xFEDCBA97n, -0xFEDCBA987654320Fn, 0xFEDCBA997530ECA6n); >+testSub(0xFEDCBA97n, -0xFEDCBA9876543210n, 0xFEDCBA997530ECA7n); >+testSub(0x1234n, 0xFEDCBA9876543210n, -0xFEDCBA9876541FDCn); >+testSub(0x1234n, 0xFEDCBA987654320Fn, -0xFEDCBA9876541FDBn); >+testSub(0x1234n, 0xFEDCBA98n, -0xFEDCA864n); >+testSub(0x1234n, 0xFEDCBA97n, -0xFEDCA863n); >+testSub(0x1234n, 0x1234n, 0x0n); >+testSub(0x1234n, 0x3n, 0x1231n); >+testSub(0x1234n, 0x2n, 0x1232n); >+testSub(0x1234n, 0x1n, 0x1233n); >+testSub(0x1234n, 0x0n, 0x1234n); >+testSub(0x1234n, -0x1n, 0x1235n); >+testSub(0x1234n, -0x2n, 0x1236n); >+testSub(0x1234n, -0x3n, 0x1237n); >+testSub(0x1234n, -0x1234n, 0x2468n); >+testSub(0x1234n, -0xFEDCBA97n, 0xFEDCCCCBn); >+testSub(0x1234n, -0xFEDCBA98n, 0xFEDCCCCCn); >+testSub(0x1234n, -0xFEDCBA987654320Fn, 0xFEDCBA9876544443n); >+testSub(0x1234n, -0xFEDCBA9876543210n, 0xFEDCBA9876544444n); >+testSub(0x3n, 0xFEDCBA9876543210n, -0xFEDCBA987654320Dn); >+testSub(0x3n, 0xFEDCBA987654320Fn, -0xFEDCBA987654320Cn); >+testSub(0x3n, 0xFEDCBA98n, -0xFEDCBA95n); >+testSub(0x3n, 0xFEDCBA97n, -0xFEDCBA94n); >+testSub(0x3n, 0x1234n, -0x1231n); >+testSub(0x3n, 0x3n, 0x0n); >+testSub(0x3n, 0x2n, 0x1n); >+testSub(0x3n, 0x1n, 0x2n); >+testSub(0x3n, 0x0n, 0x3n); >+testSub(0x3n, -0x1n, 0x4n); >+testSub(0x3n, -0x2n, 0x5n); >+testSub(0x3n, -0x3n, 0x6n); >+testSub(0x3n, -0x1234n, 0x1237n); >+testSub(0x3n, -0xFEDCBA97n, 0xFEDCBA9An); >+testSub(0x3n, -0xFEDCBA98n, 0xFEDCBA9Bn); >+testSub(0x3n, -0xFEDCBA987654320Fn, 0xFEDCBA9876543212n); >+testSub(0x3n, -0xFEDCBA9876543210n, 0xFEDCBA9876543213n); >+testSub(0x2n, 0xFEDCBA9876543210n, -0xFEDCBA987654320En); >+testSub(0x2n, 0xFEDCBA987654320Fn, -0xFEDCBA987654320Dn); >+testSub(0x2n, 0xFEDCBA98n, -0xFEDCBA96n); >+testSub(0x2n, 0xFEDCBA97n, -0xFEDCBA95n); >+testSub(0x2n, 0x1234n, -0x1232n); >+testSub(0x2n, 0x3n, -0x1n); >+testSub(0x2n, 0x2n, 0x0n); >+testSub(0x2n, 0x1n, 0x1n); >+testSub(0x2n, 0x0n, 0x2n); >+testSub(0x2n, -0x1n, 0x3n); >+testSub(0x2n, -0x2n, 0x4n); >+testSub(0x2n, -0x3n, 0x5n); >+testSub(0x2n, -0x1234n, 0x1236n); >+testSub(0x2n, -0xFEDCBA97n, 0xFEDCBA99n); >+testSub(0x2n, -0xFEDCBA98n, 0xFEDCBA9An); >+testSub(0x2n, -0xFEDCBA987654320Fn, 0xFEDCBA9876543211n); >+testSub(0x2n, -0xFEDCBA9876543210n, 0xFEDCBA9876543212n); >+testSub(0x1n, 0xFEDCBA9876543210n, -0xFEDCBA987654320Fn); >+testSub(0x1n, 0xFEDCBA987654320Fn, -0xFEDCBA987654320En); >+testSub(0x1n, 0xFEDCBA98n, -0xFEDCBA97n); >+testSub(0x1n, 0xFEDCBA97n, -0xFEDCBA96n); >+testSub(0x1n, 0x1234n, -0x1233n); >+testSub(0x1n, 0x3n, -0x2n); >+testSub(0x1n, 0x2n, -0x1n); >+testSub(0x1n, 0x1n, 0x0n); >+testSub(0x1n, 0x0n, 0x1n); >+testSub(0x1n, -0x1n, 0x2n); >+testSub(0x1n, -0x2n, 0x3n); >+testSub(0x1n, -0x3n, 0x4n); >+testSub(0x1n, -0x1234n, 0x1235n); >+testSub(0x1n, -0xFEDCBA97n, 0xFEDCBA98n); >+testSub(0x1n, -0xFEDCBA98n, 0xFEDCBA99n); >+testSub(0x1n, -0xFEDCBA987654320Fn, 0xFEDCBA9876543210n); >+testSub(0x1n, -0xFEDCBA9876543210n, 0xFEDCBA9876543211n); >+testSub(0x0n, 0xFEDCBA9876543210n, -0xFEDCBA9876543210n); >+testSub(0x0n, 0xFEDCBA987654320Fn, -0xFEDCBA987654320Fn); >+testSub(0x0n, 0xFEDCBA98n, -0xFEDCBA98n); >+testSub(0x0n, 0xFEDCBA97n, -0xFEDCBA97n); >+testSub(0x0n, 0x1234n, -0x1234n); >+testSub(0x0n, 0x3n, -0x3n); >+testSub(0x0n, 0x2n, -0x2n); >+testSub(0x0n, 0x1n, -0x1n); >+testSub(0x0n, 0x0n, 0x0n); >+testSub(0x0n, -0x1n, 0x1n); >+testSub(0x0n, -0x2n, 0x2n); >+testSub(0x0n, -0x3n, 0x3n); >+testSub(0x0n, -0x1234n, 0x1234n); >+testSub(0x0n, -0xFEDCBA97n, 0xFEDCBA97n); >+testSub(0x0n, -0xFEDCBA98n, 0xFEDCBA98n); >+testSub(0x0n, -0xFEDCBA987654320Fn, 0xFEDCBA987654320Fn); >+testSub(0x0n, -0xFEDCBA9876543210n, 0xFEDCBA9876543210n); >+testSub(-0x1n, 0xFEDCBA9876543210n, -0xFEDCBA9876543211n); >+testSub(-0x1n, 0xFEDCBA987654320Fn, -0xFEDCBA9876543210n); >+testSub(-0x1n, 0xFEDCBA98n, -0xFEDCBA99n); >+testSub(-0x1n, 0xFEDCBA97n, -0xFEDCBA98n); >+testSub(-0x1n, 0x1234n, -0x1235n); >+testSub(-0x1n, 0x3n, -0x4n); >+testSub(-0x1n, 0x2n, -0x3n); >+testSub(-0x1n, 0x1n, -0x2n); >+testSub(-0x1n, 0x0n, -0x1n); >+testSub(-0x1n, -0x1n, 0x0n); >+testSub(-0x1n, -0x2n, 0x1n); >+testSub(-0x1n, -0x3n, 0x2n); >+testSub(-0x1n, -0x1234n, 0x1233n); >+testSub(-0x1n, -0xFEDCBA97n, 0xFEDCBA96n); >+testSub(-0x1n, -0xFEDCBA98n, 0xFEDCBA97n); >+testSub(-0x1n, -0xFEDCBA987654320Fn, 0xFEDCBA987654320En); >+testSub(-0x1n, -0xFEDCBA9876543210n, 0xFEDCBA987654320Fn); >+testSub(-0x2n, 0xFEDCBA9876543210n, -0xFEDCBA9876543212n); >+testSub(-0x2n, 0xFEDCBA987654320Fn, -0xFEDCBA9876543211n); >+testSub(-0x2n, 0xFEDCBA98n, -0xFEDCBA9An); >+testSub(-0x2n, 0xFEDCBA97n, -0xFEDCBA99n); >+testSub(-0x2n, 0x1234n, -0x1236n); >+testSub(-0x2n, 0x3n, -0x5n); >+testSub(-0x2n, 0x2n, -0x4n); >+testSub(-0x2n, 0x1n, -0x3n); >+testSub(-0x2n, 0x0n, -0x2n); >+testSub(-0x2n, -0x1n, -0x1n); >+testSub(-0x2n, -0x2n, 0x0n); >+testSub(-0x2n, -0x3n, 0x1n); >+testSub(-0x2n, -0x1234n, 0x1232n); >+testSub(-0x2n, -0xFEDCBA97n, 0xFEDCBA95n); >+testSub(-0x2n, -0xFEDCBA98n, 0xFEDCBA96n); >+testSub(-0x2n, -0xFEDCBA987654320Fn, 0xFEDCBA987654320Dn); >+testSub(-0x2n, -0xFEDCBA9876543210n, 0xFEDCBA987654320En); >+testSub(-0x3n, 0xFEDCBA9876543210n, -0xFEDCBA9876543213n); >+testSub(-0x3n, 0xFEDCBA987654320Fn, -0xFEDCBA9876543212n); >+testSub(-0x3n, 0xFEDCBA98n, -0xFEDCBA9Bn); >+testSub(-0x3n, 0xFEDCBA97n, -0xFEDCBA9An); >+testSub(-0x3n, 0x1234n, -0x1237n); >+testSub(-0x3n, 0x3n, -0x6n); >+testSub(-0x3n, 0x2n, -0x5n); >+testSub(-0x3n, 0x1n, -0x4n); >+testSub(-0x3n, 0x0n, -0x3n); >+testSub(-0x3n, -0x1n, -0x2n); >+testSub(-0x3n, -0x2n, -0x1n); >+testSub(-0x3n, -0x3n, 0x0n); >+testSub(-0x3n, -0x1234n, 0x1231n); >+testSub(-0x3n, -0xFEDCBA97n, 0xFEDCBA94n); >+testSub(-0x3n, -0xFEDCBA98n, 0xFEDCBA95n); >+testSub(-0x3n, -0xFEDCBA987654320Fn, 0xFEDCBA987654320Cn); >+testSub(-0x3n, -0xFEDCBA9876543210n, 0xFEDCBA987654320Dn); >+testSub(-0x1234n, 0xFEDCBA9876543210n, -0xFEDCBA9876544444n); >+testSub(-0x1234n, 0xFEDCBA987654320Fn, -0xFEDCBA9876544443n); >+testSub(-0x1234n, 0xFEDCBA98n, -0xFEDCCCCCn); >+testSub(-0x1234n, 0xFEDCBA97n, -0xFEDCCCCBn); >+testSub(-0x1234n, 0x1234n, -0x2468n); >+testSub(-0x1234n, 0x3n, -0x1237n); >+testSub(-0x1234n, 0x2n, -0x1236n); >+testSub(-0x1234n, 0x1n, -0x1235n); >+testSub(-0x1234n, 0x0n, -0x1234n); >+testSub(-0x1234n, -0x1n, -0x1233n); >+testSub(-0x1234n, -0x2n, -0x1232n); >+testSub(-0x1234n, -0x3n, -0x1231n); >+testSub(-0x1234n, -0x1234n, 0x0n); >+testSub(-0x1234n, -0xFEDCBA97n, 0xFEDCA863n); >+testSub(-0x1234n, -0xFEDCBA98n, 0xFEDCA864n); >+testSub(-0x1234n, -0xFEDCBA987654320Fn, 0xFEDCBA9876541FDBn); >+testSub(-0x1234n, -0xFEDCBA9876543210n, 0xFEDCBA9876541FDCn); >+testSub(-0xFEDCBA97n, 0xFEDCBA9876543210n, -0xFEDCBA997530ECA7n); >+testSub(-0xFEDCBA97n, 0xFEDCBA987654320Fn, -0xFEDCBA997530ECA6n); >+testSub(-0xFEDCBA97n, 0xFEDCBA98n, -0x1FDB9752Fn); >+testSub(-0xFEDCBA97n, 0xFEDCBA97n, -0x1FDB9752En); >+testSub(-0xFEDCBA97n, 0x1234n, -0xFEDCCCCBn); >+testSub(-0xFEDCBA97n, 0x3n, -0xFEDCBA9An); >+testSub(-0xFEDCBA97n, 0x2n, -0xFEDCBA99n); >+testSub(-0xFEDCBA97n, 0x1n, -0xFEDCBA98n); >+testSub(-0xFEDCBA97n, 0x0n, -0xFEDCBA97n); >+testSub(-0xFEDCBA97n, -0x1n, -0xFEDCBA96n); >+testSub(-0xFEDCBA97n, -0x2n, -0xFEDCBA95n); >+testSub(-0xFEDCBA97n, -0x3n, -0xFEDCBA94n); >+testSub(-0xFEDCBA97n, -0x1234n, -0xFEDCA863n); >+testSub(-0xFEDCBA97n, -0xFEDCBA97n, 0x0n); >+testSub(-0xFEDCBA97n, -0xFEDCBA98n, 0x1n); >+testSub(-0xFEDCBA97n, -0xFEDCBA987654320Fn, 0xFEDCBA9777777778n); >+testSub(-0xFEDCBA97n, -0xFEDCBA9876543210n, 0xFEDCBA9777777779n); >+testSub(-0xFEDCBA98n, 0xFEDCBA9876543210n, -0xFEDCBA997530ECA8n); >+testSub(-0xFEDCBA98n, 0xFEDCBA987654320Fn, -0xFEDCBA997530ECA7n); >+testSub(-0xFEDCBA98n, 0xFEDCBA98n, -0x1FDB97530n); >+testSub(-0xFEDCBA98n, 0xFEDCBA97n, -0x1FDB9752Fn); >+testSub(-0xFEDCBA98n, 0x1234n, -0xFEDCCCCCn); >+testSub(-0xFEDCBA98n, 0x3n, -0xFEDCBA9Bn); >+testSub(-0xFEDCBA98n, 0x2n, -0xFEDCBA9An); >+testSub(-0xFEDCBA98n, 0x1n, -0xFEDCBA99n); >+testSub(-0xFEDCBA98n, 0x0n, -0xFEDCBA98n); >+testSub(-0xFEDCBA98n, -0x1n, -0xFEDCBA97n); >+testSub(-0xFEDCBA98n, -0x2n, -0xFEDCBA96n); >+testSub(-0xFEDCBA98n, -0x3n, -0xFEDCBA95n); >+testSub(-0xFEDCBA98n, -0x1234n, -0xFEDCA864n); >+testSub(-0xFEDCBA98n, -0xFEDCBA97n, -0x1n); >+testSub(-0xFEDCBA98n, -0xFEDCBA98n, 0x0n); >+testSub(-0xFEDCBA98n, -0xFEDCBA987654320Fn, 0xFEDCBA9777777777n); >+testSub(-0xFEDCBA98n, -0xFEDCBA9876543210n, 0xFEDCBA9777777778n); >+testSub(-0xFEDCBA987654320Fn, 0xFEDCBA9876543210n, -0x1FDB97530ECA8641Fn); >+testSub(-0xFEDCBA987654320Fn, 0xFEDCBA987654320Fn, -0x1FDB97530ECA8641En); >+testSub(-0xFEDCBA987654320Fn, 0xFEDCBA98n, -0xFEDCBA997530ECA7n); >+testSub(-0xFEDCBA987654320Fn, 0xFEDCBA97n, -0xFEDCBA997530ECA6n); >+testSub(-0xFEDCBA987654320Fn, 0x1234n, -0xFEDCBA9876544443n); >+testSub(-0xFEDCBA987654320Fn, 0x3n, -0xFEDCBA9876543212n); >+testSub(-0xFEDCBA987654320Fn, 0x2n, -0xFEDCBA9876543211n); >+testSub(-0xFEDCBA987654320Fn, 0x1n, -0xFEDCBA9876543210n); >+testSub(-0xFEDCBA987654320Fn, 0x0n, -0xFEDCBA987654320Fn); >+testSub(-0xFEDCBA987654320Fn, -0x1n, -0xFEDCBA987654320En); >+testSub(-0xFEDCBA987654320Fn, -0x2n, -0xFEDCBA987654320Dn); >+testSub(-0xFEDCBA987654320Fn, -0x3n, -0xFEDCBA987654320Cn); >+testSub(-0xFEDCBA987654320Fn, -0x1234n, -0xFEDCBA9876541FDBn); >+testSub(-0xFEDCBA987654320Fn, -0xFEDCBA97n, -0xFEDCBA9777777778n); >+testSub(-0xFEDCBA987654320Fn, -0xFEDCBA98n, -0xFEDCBA9777777777n); >+testSub(-0xFEDCBA987654320Fn, -0xFEDCBA987654320Fn, 0x0n); >+testSub(-0xFEDCBA987654320Fn, -0xFEDCBA9876543210n, 0x1n); >+testSub(-0xFEDCBA9876543210n, 0xFEDCBA9876543210n, -0x1FDB97530ECA86420n); >+testSub(-0xFEDCBA9876543210n, 0xFEDCBA987654320Fn, -0x1FDB97530ECA8641Fn); >+testSub(-0xFEDCBA9876543210n, 0xFEDCBA98n, -0xFEDCBA997530ECA8n); >+testSub(-0xFEDCBA9876543210n, 0xFEDCBA97n, -0xFEDCBA997530ECA7n); >+testSub(-0xFEDCBA9876543210n, 0x1234n, -0xFEDCBA9876544444n); >+testSub(-0xFEDCBA9876543210n, 0x3n, -0xFEDCBA9876543213n); >+testSub(-0xFEDCBA9876543210n, 0x2n, -0xFEDCBA9876543212n); >+testSub(-0xFEDCBA9876543210n, 0x1n, -0xFEDCBA9876543211n); >+testSub(-0xFEDCBA9876543210n, 0x0n, -0xFEDCBA9876543210n); >+testSub(-0xFEDCBA9876543210n, -0x1n, -0xFEDCBA987654320Fn); >+testSub(-0xFEDCBA9876543210n, -0x2n, -0xFEDCBA987654320En); >+testSub(-0xFEDCBA9876543210n, -0x3n, -0xFEDCBA987654320Dn); >+testSub(-0xFEDCBA9876543210n, -0x1234n, -0xFEDCBA9876541FDCn); >+testSub(-0xFEDCBA9876543210n, -0xFEDCBA97n, -0xFEDCBA9777777779n); >+testSub(-0xFEDCBA9876543210n, -0xFEDCBA98n, -0xFEDCBA9777777778n); >+testSub(-0xFEDCBA9876543210n, -0xFEDCBA987654320Fn, -0x1n); >+testSub(-0xFEDCBA9876543210n, -0xFEDCBA9876543210n, 0x0n); >+ >diff --git a/JSTests/stress/big-int-subtraction-jit.js b/JSTests/stress/big-int-subtraction-jit.js >new file mode 100644 >index 0000000..cb081aa >--- /dev/null >+++ b/JSTests/stress/big-int-subtraction-jit.js >@@ -0,0 +1,19 @@ >+//@ runBigIntEnabled >+ >+let assert = { >+ sameValue: function(i, e, m) { >+ if (i !== e) >+ throw new Error(m); >+ } >+} >+ >+function bigIntAddition(x, y) { >+ return x - y; >+} >+noInline(bigIntAddition); >+ >+for (let i = 0; i < 10000; i++) { >+ let r = bigIntAddition(3n, 10n); >+ assert.sameValue(r, -7n, 3n + " - " + 10n + " = " + r); >+} >+ >diff --git a/JSTests/stress/big-int-subtraction-type-error.js b/JSTests/stress/big-int-subtraction-type-error.js >new file mode 100644 >index 0000000..74ac48a >--- /dev/null >+++ b/JSTests/stress/big-int-subtraction-type-error.js >@@ -0,0 +1,125 @@ >+//@ runBigIntEnabled >+ >+function assert(a, message) { >+ if (!a) >+ throw new Error(message); >+} >+ >+function assertThrowTypeError(a, b, message) { >+ try { >+ let n = a - b; >+ assert(false, message + ": Should throw TypeError, but executed without exception"); >+ } catch (e) { >+ assert(e instanceof TypeError, message + ": expected TypeError, got: " + e); >+ } >+} >+ >+assertThrowTypeError(30n, Symbol("foo"), "BingInt - Symbol"); >+assertThrowTypeError(Symbol("bar"), 18757382984821n, "Symbol - BigInt"); >+assertThrowTypeError(30n, 3320, "BingInt - Int32"); >+assertThrowTypeError(33256, 18757382984821n, "Int32 - BigInt"); >+assertThrowTypeError(30n, 0.543, "BingInt - Double"); >+assertThrowTypeError(230.19293, 18757382984821n, "Double - BigInt"); >+assertThrowTypeError(18757382984821n, "abc", "BigInt - String"); >+assertThrowTypeError("def", 18757382984821n, "String - BigInt"); >+assertThrowTypeError(18757382984821n, "", "BigInt - Empty String"); >+assertThrowTypeError("", 18757382984821n, "Empty - BigInt"); >+assertThrowTypeError(18757382984821n, NaN, "BigInt - NaN"); >+assertThrowTypeError(NaN, 18757382984821n, "NaN - BigInt"); >+assertThrowTypeError(18757382984821n, undefined, "BigInt - undefined"); >+assertThrowTypeError(undefined, 18757382984821n, "undefined - BigInt"); >+assertThrowTypeError(18757382984821n, true, "BigInt - true"); >+assertThrowTypeError(true, 18757382984821n, "true - BigInt"); >+assertThrowTypeError(18757382984821n, false, "BigInt - false"); >+assertThrowTypeError(false, 18757382984821n, "false - BigInt"); >+assertThrowTypeError(18757382984821n, +Infinity, "BigInt - Infinity"); >+assertThrowTypeError(+Infinity, 18757382984821n, "Infinity - BigInt"); >+assertThrowTypeError(18757382984821n, -Infinity, "BigInt - -Infinity"); >+assertThrowTypeError(-Infinity, 18757382984821n, "-Infinity - BigInt"); >+ >+// Error when returning from object >+ >+let o = { >+ valueOf: function () { return Symbol("Foo"); } >+}; >+ >+assertThrowTypeError(30n, o, "BingInt - Object.valueOf returning Symbol"); >+assertThrowTypeError(o, 18757382984821n, "Object.valueOf returning Symbol - BigInt"); >+ >+o = { >+ valueOf: function () { return 33256; } >+}; >+ >+assertThrowTypeError(30n, o, "BingInt - Object.valueOf returning Int32"); >+assertThrowTypeError(o, 18757382984821n, "Object.valueOf returning Int32 - BigInt"); >+ >+o = { >+ valueOf: function () { return 0.453; } >+}; >+ >+assertThrowTypeError(30n, o, "BingInt - Object.valueOf returning Double"); >+assertThrowTypeError(o, 18757382984821n, "Object.valueOf returning Double - BigInt"); >+ >+o = { >+ valueOf: function () { return ""; } >+}; >+ >+assertThrowTypeError(30n, o, "BingInt - Object.valueOf returning String"); >+assertThrowTypeError(o, 18757382984821n, "Object.valueOf returning String - BigInt"); >+ >+o = { >+ toString: function () { return Symbol("Foo"); } >+}; >+ >+assertThrowTypeError(30n, o, "BingInt - Object.toString returning Symbol"); >+assertThrowTypeError(o, 18757382984821n, "Object.toString returning Symbol - BigInt"); >+ >+o = { >+ toString: function () { return 33256; } >+}; >+ >+assertThrowTypeError(30n, o, "BingInt - Object.toString returning Int32"); >+assertThrowTypeError(o, 18757382984821n, "Object.toString returning Int32 - BigInt"); >+ >+o = { >+ toString: function () { return 0.453; } >+}; >+ >+assertThrowTypeError(30n, o, "BingInt - Object.toString returning Double"); >+assertThrowTypeError(o, 18757382984821n, "Object.toString returning Double - BigInt"); >+ >+o = { >+ toString: function () { return "abc"; } >+}; >+ >+assertThrowTypeError(30n, o, "BingInt - Object.toString returning String"); >+assertThrowTypeError(o, 18757382984821n, "Object.toString returning String - BigInt"); >+ >+o = { >+ [Symbol.toPrimitive]: function () { return Symbol("Foo"); } >+}; >+ >+assertThrowTypeError(30n, o, "BingInt - Object.@@toPrimitive returning Symbol"); >+assertThrowTypeError(o, 18757382984821n, "Object.@@toPrimitive returning Symbol - BigInt"); >+ >+o = { >+ [Symbol.toPrimitive]: function () { return 33256; } >+}; >+ >+assertThrowTypeError(30n, o, "BingInt - Object.@@toPrimitive returning Int32"); >+assertThrowTypeError(o, 18757382984821n, "Object.@@toPrimitive returning Int32 - BigInt"); >+ >+o = { >+ [Symbol.toPrimitive]: function () { return 0.453; } >+}; >+ >+assertThrowTypeError(30n, o, "BingInt - Object.@@toPrimitive returning Double"); >+assertThrowTypeError(o, 18757382984821n, "Object.@@toPrimitive returning Double - BigInt"); >+ >+o = { >+ [Symbol.toPrimitive]: function () { return "Abc"; } >+}; >+ >+assertThrowTypeError(30n, o, "BingInt - Object.@@toPrimitive returning String"); >+assertThrowTypeError(o, 18757382984821n, "Object.@@toPrimitive returning String - BigInt"); >+ >diff --git a/JSTests/stress/sub-order-evaluation.js b/JSTests/stress/sub-order-evaluation.js >new file mode 100644 >index 0000000..21f9234 >--- /dev/null >+++ b/JSTests/stress/sub-order-evaluation.js >@@ -0,0 +1,27 @@ >+function assert(a, message) { >+ if (!a) >+ throw new Error(message); >+} >+ >+function assertThrowTypeError(a, b, message) { >+ try { >+ let n = a - b; >+ assert(false, message + ": Should throw TypeError, but executed without exception"); >+ } catch (e) { >+ assert(e instanceof TypeError, message + ": expected TypeError, got: " + e); >+ } >+} >+ >+let o = { >+ valueOf: function () { throw new Error("Oops"); } >+}; >+ >+assertThrowTypeError(Symbol("3"), o, "Symbol + Object should throw TypeError"); >+ >+try { >+ let n = o - Symbol("3"); >+ assert(false, message + ": Should throw Error, but executed without exception"); >+} catch (e) { >+ assert(e.message === "Oops","Expected Error('Oops'), got: " + e); >+} >+ >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 92185c8..e6166ee 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,40 @@ >+2018-06-01 Caio Lima <ticaiolima@gmail.com> >+ >+ [ESNext][BigInt] Implement support for addition operations >+ https://bugs.webkit.org/show_bug.cgi?id=179002 >+ >+ Reviewed by Yusuke Suzuki. >+ >+ This patch is implementing support to BigInt Operands into binary "+" >+ and binary "-" operators. Right now, we have limited support to DFG >+ and FTL JIT layers, but we plan to fix this support in future >+ patches. >+ >+ * jit/JITOperations.cpp: >+ * runtime/CommonSlowPaths.cpp: >+ (JSC::SLOW_PATH_DECL): >+ * runtime/JSBigInt.cpp: >+ (JSC::JSBigInt::parseInt): >+ (JSC::JSBigInt::stringToBigInt): >+ (JSC::JSBigInt::toString): >+ (JSC::JSBigInt::multiply): >+ (JSC::JSBigInt::divide): >+ (JSC::JSBigInt::remainder): >+ (JSC::JSBigInt::add): >+ (JSC::JSBigInt::sub): >+ (JSC::JSBigInt::absoluteAdd): >+ (JSC::JSBigInt::absoluteSub): >+ (JSC::JSBigInt::toStringGeneric): >+ (JSC::JSBigInt::allocateFor): >+ (JSC::JSBigInt::toNumber const): >+ (JSC::JSBigInt::getPrimitiveNumber const): >+ * runtime/JSBigInt.h: >+ * runtime/JSCJSValueInlines.h: >+ * runtime/Operations.cpp: >+ (JSC::jsAddSlowCase): >+ * runtime/Operations.h: >+ (JSC::jsSub): >+ > 2018-06-01 Wenson Hsieh <wenson_hsieh@apple.com> > > Fix the watchOS build after r232385 >diff --git a/Source/JavaScriptCore/jit/JITOperations.cpp b/Source/JavaScriptCore/jit/JITOperations.cpp >index d381c1d..4bfd122 100644 >--- a/Source/JavaScriptCore/jit/JITOperations.cpp >+++ b/Source/JavaScriptCore/jit/JITOperations.cpp >@@ -2816,34 +2816,23 @@ EncodedJSValue JIT_OPERATION operationArithNegateOptimize(ExecState* exec, Encod > return JSValue::encode(jsNumber(-number)); > } > >-ALWAYS_INLINE static EncodedJSValue unprofiledSub(VM& vm, ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) >+ALWAYS_INLINE static EncodedJSValue unprofiledSub(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) > { >- auto scope = DECLARE_THROW_SCOPE(vm); > JSValue op1 = JSValue::decode(encodedOp1); > JSValue op2 = JSValue::decode(encodedOp2); >- >- double a = op1.toNumber(exec); >- RETURN_IF_EXCEPTION(scope, encodedJSValue()); >- scope.release(); >- double b = op2.toNumber(exec); >- return JSValue::encode(jsNumber(a - b)); >+ >+ return JSValue::encode(jsSub(exec, op1, op2)); > } > >-ALWAYS_INLINE static EncodedJSValue profiledSub(VM& vm, ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true) >+ALWAYS_INLINE static EncodedJSValue profiledSub(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true) > { >- auto scope = DECLARE_THROW_SCOPE(vm); > JSValue op1 = JSValue::decode(encodedOp1); > JSValue op2 = JSValue::decode(encodedOp2); > > if (shouldObserveLHSAndRHSTypes) > arithProfile.observeLHSAndRHS(op1, op2); > >- double a = op1.toNumber(exec); >- RETURN_IF_EXCEPTION(scope, encodedJSValue()); >- double b = op2.toNumber(exec); >- RETURN_IF_EXCEPTION(scope, encodedJSValue()); >- >- JSValue result = jsNumber(a - b); >+ JSValue result = jsSub(exec, op1, op2); > arithProfile.observeResult(result); > return JSValue::encode(result); > } >@@ -2852,7 +2841,7 @@ EncodedJSValue JIT_OPERATION operationValueSub(ExecState* exec, EncodedJSValue e > { > VM* vm = &exec->vm(); > NativeCallFrameTracer tracer(vm, exec); >- return unprofiledSub(*vm, exec, encodedOp1, encodedOp2); >+ return unprofiledSub(exec, encodedOp1, encodedOp2); > } > > EncodedJSValue JIT_OPERATION operationValueSubProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile) >@@ -2862,7 +2851,7 @@ EncodedJSValue JIT_OPERATION operationValueSubProfiled(ExecState* exec, EncodedJ > VM* vm = &exec->vm(); > NativeCallFrameTracer tracer(vm, exec); > >- return profiledSub(*vm, exec, encodedOp1, encodedOp2, *arithProfile); >+ return profiledSub(exec, encodedOp1, encodedOp2, *arithProfile); > } > > EncodedJSValue JIT_OPERATION operationValueSubOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC* subIC) >@@ -2879,7 +2868,7 @@ EncodedJSValue JIT_OPERATION operationValueSubOptimize(ExecState* exec, EncodedJ > exec->codeBlock()->dumpMathICStats(); > #endif > >- return unprofiledSub(*vm, exec, encodedOp1, encodedOp2); >+ return unprofiledSub(exec, encodedOp1, encodedOp2); > } > > EncodedJSValue JIT_OPERATION operationValueSubNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) >@@ -2887,7 +2876,7 @@ EncodedJSValue JIT_OPERATION operationValueSubNoOptimize(ExecState* exec, Encode > VM* vm = &exec->vm(); > NativeCallFrameTracer tracer(vm, exec); > >- return unprofiledSub(*vm, exec, encodedOp1, encodedOp2); >+ return unprofiledSub(exec, encodedOp1, encodedOp2); > } > > EncodedJSValue JIT_OPERATION operationValueSubProfiledOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC* subIC) >@@ -2905,7 +2894,7 @@ EncodedJSValue JIT_OPERATION operationValueSubProfiledOptimize(ExecState* exec, > exec->codeBlock()->dumpMathICStats(); > #endif > >- return profiledSub(*vm, exec, encodedOp1, encodedOp2, *arithProfile, false); >+ return profiledSub(exec, encodedOp1, encodedOp2, *arithProfile, false); > } > > EncodedJSValue JIT_OPERATION operationValueSubProfiledNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC* subIC) >@@ -2915,7 +2904,7 @@ EncodedJSValue JIT_OPERATION operationValueSubProfiledNoOptimize(ExecState* exec > > ArithProfile* arithProfile = subIC->arithProfile(); > ASSERT(arithProfile); >- return profiledSub(*vm, exec, encodedOp1, encodedOp2, *arithProfile); >+ return profiledSub(exec, encodedOp1, encodedOp2, *arithProfile); > } > > void JIT_OPERATION operationProcessTypeProfilerLog(ExecState* exec) >diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >index b7f093e..2b82170 100644 >--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >@@ -405,7 +405,7 @@ SLOW_PATH_DECL(slow_path_negate) > CHECK_EXCEPTION(); > > if (primValue.isBigInt()) { >- JSBigInt* result = JSBigInt::unaryMinus(exec->vm(), asBigInt(primValue)); >+ JSBigInt* result = JSBigInt::unaryMinus(vm, asBigInt(primValue)); > RETURN_WITH_PROFILING(result, { > updateArithProfileForUnaryArithOp(pc, result, operand); > }); >@@ -517,10 +517,24 @@ SLOW_PATH_DECL(slow_path_sub) > BEGIN(); > JSValue left = OP_C(2).jsValue(); > JSValue right = OP_C(3).jsValue(); >- double a = left.toNumber(exec); >- if (UNLIKELY(throwScope.exception())) >- RETURN(JSValue()); >- double b = right.toNumber(exec); >+ auto leftNumeric = left.toNumeric(exec); >+ CHECK_EXCEPTION(); >+ auto rightNumeric = right.toNumeric(exec); >+ CHECK_EXCEPTION(); >+ >+ if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) { >+ if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) { >+ JSBigInt* result = JSBigInt::sub(vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); >+ RETURN_WITH_PROFILING(result, { >+ updateArithProfileForBinaryArithOp(exec, pc, result, left, right); >+ }); >+ } >+ >+ THROW(createTypeError(exec, "Invalid mix of BigInt and other type in subtraction.")); >+ } >+ >+ double a = WTF::get<double>(leftNumeric); >+ double b = WTF::get<double>(rightNumeric); > JSValue result = jsNumber(a - b); > RETURN_WITH_PROFILING(result, { > updateArithProfileForBinaryArithOp(exec, pc, result, left, right); >@@ -539,7 +553,7 @@ SLOW_PATH_DECL(slow_path_div) > > if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) { > if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) { >- JSValue result(JSBigInt::divide(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric))); >+ JSBigInt* result = JSBigInt::divide(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); > CHECK_EXCEPTION(); > RETURN_WITH_PROFILING(result, { > updateArithProfileForBinaryArithOp(exec, pc, result, left, right); >diff --git a/Source/JavaScriptCore/runtime/JSBigInt.cpp b/Source/JavaScriptCore/runtime/JSBigInt.cpp >index 6742d9b..4e89641 100644 >--- a/Source/JavaScriptCore/runtime/JSBigInt.cpp >+++ b/Source/JavaScriptCore/runtime/JSBigInt.cpp >@@ -195,31 +195,31 @@ std::optional<uint8_t> JSBigInt::singleDigitValueForString() > return { }; > } > >-JSBigInt* JSBigInt::parseInt(ExecState* state, StringView s, ErrorParseMode parserMode) >+JSBigInt* JSBigInt::parseInt(ExecState* exec, StringView s, ErrorParseMode parserMode) > { > if (s.is8Bit()) >- return parseInt(state, s.characters8(), s.length(), parserMode); >- return parseInt(state, s.characters16(), s.length(), parserMode); >+ return parseInt(exec, s.characters8(), s.length(), parserMode); >+ return parseInt(exec, s.characters16(), s.length(), parserMode); > } > >-JSBigInt* JSBigInt::parseInt(ExecState* state, VM& vm, StringView s, uint8_t radix, ErrorParseMode parserMode, ParseIntSign sign) >+JSBigInt* JSBigInt::parseInt(ExecState* exec, VM& vm, StringView s, uint8_t radix, ErrorParseMode parserMode, ParseIntSign sign) > { > if (s.is8Bit()) >- return parseInt(state, vm, s.characters8(), s.length(), 0, radix, parserMode, sign, ParseIntMode::DisallowEmptyString); >- return parseInt(state, vm, s.characters16(), s.length(), 0, radix, parserMode, sign, ParseIntMode::DisallowEmptyString); >+ return parseInt(exec, vm, s.characters8(), s.length(), 0, radix, parserMode, sign, ParseIntMode::DisallowEmptyString); >+ return parseInt(exec, vm, s.characters16(), s.length(), 0, radix, parserMode, sign, ParseIntMode::DisallowEmptyString); > } > >-JSBigInt* JSBigInt::stringToBigInt(ExecState* state, StringView s) >+JSBigInt* JSBigInt::stringToBigInt(ExecState* exec, StringView s) > { >- return parseInt(state, s, ErrorParseMode::IgnoreExceptions); >+ return parseInt(exec, s, ErrorParseMode::IgnoreExceptions); > } > >-String JSBigInt::toString(ExecState* state, unsigned radix) >+String JSBigInt::toString(ExecState* exec, unsigned radix) > { > if (this->isZero()) >- return state->vm().smallStrings.singleCharacterStringRep('0'); >+ return exec->vm().smallStrings.singleCharacterStringRep('0'); > >- return toStringGeneric(state, this, radix); >+ return toStringGeneric(exec, this, radix); > } > > inline bool JSBigInt::isZero() >@@ -237,9 +237,9 @@ inline void JSBigInt::inplaceMultiplyAdd(uintptr_t factor, uintptr_t summand) > internalMultiplyAdd(this, factor, summand, length(), this); > } > >-JSBigInt* JSBigInt::multiply(ExecState* state, JSBigInt* x, JSBigInt* y) >+JSBigInt* JSBigInt::multiply(ExecState* exec, JSBigInt* x, JSBigInt* y) > { >- VM& vm = state->vm(); >+ VM& vm = exec->vm(); > > if (x->isZero()) > return x; >@@ -257,14 +257,14 @@ JSBigInt* JSBigInt::multiply(ExecState* state, JSBigInt* x, JSBigInt* y) > return result->rightTrim(vm); > } > >-JSBigInt* JSBigInt::divide(ExecState* state, JSBigInt* x, JSBigInt* y) >+JSBigInt* JSBigInt::divide(ExecState* exec, JSBigInt* x, JSBigInt* y) > { > // 1. If y is 0n, throw a RangeError exception. >- VM& vm = state->vm(); >+ VM& vm = exec->vm(); > auto scope = DECLARE_THROW_SCOPE(vm); > > if (y->isZero()) { >- throwRangeError(state, scope, ASCIILiteral("0 is an invalid divisor value.")); >+ throwRangeError(exec, scope, ASCIILiteral("0 is an invalid divisor value.")); > return nullptr; > } > >@@ -310,14 +310,14 @@ JSBigInt* JSBigInt::unaryMinus(VM& vm, JSBigInt* x) > return result; > } > >-JSBigInt* JSBigInt::remainder(ExecState* state, JSBigInt* x, JSBigInt* y) >+JSBigInt* JSBigInt::remainder(ExecState* exec, JSBigInt* x, JSBigInt* y) > { > // 1. If y is 0n, throw a RangeError exception. >- VM& vm = state->vm(); >+ VM& vm = exec->vm(); > auto scope = DECLARE_THROW_SCOPE(vm); > > if (y->isZero()) { >- throwRangeError(state, scope, ASCIILiteral("0 is an invalid divisor value.")); >+ throwRangeError(exec, scope, ASCIILiteral("0 is an invalid divisor value.")); > return nullptr; > } > >@@ -346,6 +346,40 @@ JSBigInt* JSBigInt::remainder(ExecState* state, JSBigInt* x, JSBigInt* y) > return remainder->rightTrim(vm); > } > >+JSBigInt* JSBigInt::add(VM& vm, JSBigInt* x, JSBigInt* y) >+{ >+ bool xSign = x->sign(); >+ >+ // x + y == x + y >+ // -x + -y == -(x + y) >+ if (xSign == y->sign()) >+ return absoluteAdd(vm, x, y, xSign); >+ >+ // x + -y == x - y == -(y - x) >+ // -x + y == y - x == -(x - y) >+ ComparisonResult comparisonResult = absoluteCompare(x, y); >+ if (comparisonResult == ComparisonResult::GreaterThan || comparisonResult == ComparisonResult::Equal) >+ return absoluteSub(vm, x, y, xSign); >+ >+ return absoluteSub(vm, y, x, !xSign); >+} >+ >+JSBigInt* JSBigInt::sub(VM& vm, JSBigInt* x, JSBigInt* y) >+{ >+ bool xSign = x->sign(); >+ if (xSign != y->sign()) { >+ // x - (-y) == x + y >+ // (-x) - y == -(x + y) >+ return absoluteAdd(vm, x, y, xSign); >+ } >+ // x - y == -(y - x) >+ // (-x) - (-y) == y - x == -(x - y) >+ ComparisonResult comparisonResult = absoluteCompare(x, y); >+ if (comparisonResult == ComparisonResult::GreaterThan || comparisonResult == ComparisonResult::Equal) >+ return absoluteSub(vm, x, y, xSign); >+ >+ return absoluteSub(vm, y, x, !xSign); >+} > > #if USE(JSVALUE32_64) > #define HAVE_TWO_DIGIT 1 >@@ -644,6 +678,85 @@ inline JSBigInt::ComparisonResult JSBigInt::absoluteCompare(JSBigInt* x, JSBigIn > return x->digit(i) > y->digit(i) ? ComparisonResult::GreaterThan : ComparisonResult::LessThan; > } > >+JSBigInt* JSBigInt::absoluteAdd(VM& vm, JSBigInt* x, JSBigInt* y, bool resultSign) >+{ >+ if (x->length() < y->length()) >+ return absoluteAdd(vm, y, x, resultSign); >+ >+ if (x->isZero()) { >+ ASSERT(y->isZero()); >+ return x; >+ } >+ >+ if (y->isZero()) >+ return resultSign == x->sign() ? x : unaryMinus(vm, x); >+ >+ JSBigInt* result = JSBigInt::createWithLength(vm, x->length() + 1); >+ ASSERT(result); >+ Digit carry = 0; >+ unsigned i = 0; >+ for (; i < y->length(); i++) { >+ Digit newCarry = 0; >+ Digit sum = digitAdd(x->digit(i), y->digit(i), newCarry); >+ sum = digitAdd(sum, carry, newCarry); >+ result->setDigit(i, sum); >+ carry = newCarry; >+ } >+ >+ for (; i < x->length(); i++) { >+ Digit newCarry = 0; >+ Digit sum = digitAdd(x->digit(i), carry, newCarry); >+ result->setDigit(i, sum); >+ carry = newCarry; >+ } >+ >+ result->setDigit(i, carry); >+ result->setSign(resultSign); >+ >+ return result->rightTrim(vm); >+} >+ >+JSBigInt* JSBigInt::absoluteSub(VM& vm, JSBigInt* x, JSBigInt* y, bool resultSign) >+{ >+ ComparisonResult comparisonResult = absoluteCompare(x, y); >+ ASSERT(x->length() >= y->length()); >+ ASSERT(comparisonResult == ComparisonResult::GreaterThan || comparisonResult == ComparisonResult::Equal); >+ >+ if (x->isZero()) { >+ ASSERT(y->isZero()); >+ return x; >+ } >+ >+ if (y->isZero()) >+ return resultSign == x->sign() ? x : unaryMinus(vm, x); >+ >+ if (comparisonResult == ComparisonResult::Equal) >+ return JSBigInt::createZero(vm); >+ >+ JSBigInt* result = JSBigInt::createWithLength(vm, x->length()); >+ Digit borrow = 0; >+ unsigned i = 0; >+ for (; i < y->length(); i++) { >+ Digit newBorrow = 0; >+ Digit difference = digitSub(x->digit(i), y->digit(i), newBorrow); >+ difference = digitSub(difference, borrow, newBorrow); >+ result->setDigit(i, difference); >+ borrow = newBorrow; >+ } >+ >+ for (; i < x->length(); i++) { >+ Digit newBorrow = 0; >+ Digit difference = digitSub(x->digit(i), borrow, newBorrow); >+ result->setDigit(i, difference); >+ borrow = newBorrow; >+ } >+ >+ ASSERT(!borrow); >+ result->setSign(resultSign); >+ result->rightTrim(vm); >+ return result; >+} >+ > // Divides {x} by {divisor}, returning the result in {quotient} and {remainder}. > // Mathematically, the contract is: > // quotient = (x - remainder) / divisor, with 0 <= remainder < divisor. >@@ -928,13 +1041,13 @@ uint64_t JSBigInt::calculateMaximumCharactersRequired(unsigned length, unsigned > return maximumCharactersRequired; > } > >-String JSBigInt::toStringGeneric(ExecState* state, JSBigInt* x, unsigned radix) >+String JSBigInt::toStringGeneric(ExecState* exec, JSBigInt* x, unsigned radix) > { > // FIXME: [JSC] Revisit usage of Vector into JSBigInt::toString > // https://bugs.webkit.org/show_bug.cgi?id=18067 > Vector<LChar> resultString; > >- VM& vm = state->vm(); >+ VM& vm = exec->vm(); > > ASSERT(radix >= 2 && radix <= 36); > ASSERT(!x->isZero()); >@@ -947,7 +1060,7 @@ String JSBigInt::toStringGeneric(ExecState* state, JSBigInt* x, unsigned radix) > > if (maximumCharactersRequired > JSString::MaxLength) { > auto scope = DECLARE_THROW_SCOPE(vm); >- throwOutOfMemoryError(state, scope); >+ throwOutOfMemoryError(exec, scope); > return String(); > } > >@@ -1042,7 +1155,7 @@ JSBigInt* JSBigInt::rightTrim(VM& vm) > return trimmedBigInt; > } > >-JSBigInt* JSBigInt::allocateFor(ExecState* state, VM& vm, unsigned radix, unsigned charcount) >+JSBigInt* JSBigInt::allocateFor(ExecState* exec, VM& vm, unsigned radix, unsigned charcount) > { > ASSERT(2 <= radix && radix <= 36); > >@@ -1064,9 +1177,9 @@ JSBigInt* JSBigInt::allocateFor(ExecState* state, VM& vm, unsigned radix, unsign > } > } > >- if (state) { >+ if (exec) { > auto scope = DECLARE_THROW_SCOPE(vm); >- throwOutOfMemoryError(state, scope); >+ throwOutOfMemoryError(exec, scope); > } > return nullptr; > } >@@ -1076,18 +1189,18 @@ size_t JSBigInt::estimatedSize(JSCell* cell) > return Base::estimatedSize(cell) + jsCast<JSBigInt*>(cell)->m_length * sizeof(Digit); > } > >-double JSBigInt::toNumber(ExecState* state) const >+double JSBigInt::toNumber(ExecState* exec) const > { >- VM& vm = state->vm(); >+ VM& vm = exec->vm(); > auto scope = DECLARE_THROW_SCOPE(vm); >- throwTypeError(state, scope, ASCIILiteral("Conversion from 'BigInt' to 'number' is not allowed.")); >+ throwTypeError(exec, scope, ASCIILiteral("Conversion from 'BigInt' to 'number' is not allowed.")); > return 0.0; > } > >-bool JSBigInt::getPrimitiveNumber(ExecState* state, double& number, JSValue& result) const >+bool JSBigInt::getPrimitiveNumber(ExecState* exec, double& number, JSValue& result) const > { > result = this; >- number = toNumber(state); >+ number = toNumber(exec); > return true; > } > >@@ -1097,9 +1210,9 @@ inline size_t JSBigInt::offsetOfData() > } > > template <typename CharType> >-JSBigInt* JSBigInt::parseInt(ExecState* state, CharType* data, unsigned length, ErrorParseMode errorParseMode) >+JSBigInt* JSBigInt::parseInt(ExecState* exec, CharType* data, unsigned length, ErrorParseMode errorParseMode) > { >- VM& vm = state->vm(); >+ VM& vm = exec->vm(); > > unsigned p = 0; > while (p < length && isStrWhiteSpace(data[p])) >@@ -1108,13 +1221,13 @@ JSBigInt* JSBigInt::parseInt(ExecState* state, CharType* data, unsigned length, > // Check Radix from frist characters > if (static_cast<unsigned>(p) + 1 < static_cast<unsigned>(length) && data[p] == '0') { > if (isASCIIAlphaCaselessEqual(data[p + 1], 'b')) >- return parseInt(state, vm, data, length, p + 2, 2, errorParseMode, ParseIntSign::Unsigned, ParseIntMode::DisallowEmptyString); >+ return parseInt(exec, vm, data, length, p + 2, 2, errorParseMode, ParseIntSign::Unsigned, ParseIntMode::DisallowEmptyString); > > if (isASCIIAlphaCaselessEqual(data[p + 1], 'x')) >- return parseInt(state, vm, data, length, p + 2, 16, errorParseMode, ParseIntSign::Unsigned, ParseIntMode::DisallowEmptyString); >+ return parseInt(exec, vm, data, length, p + 2, 16, errorParseMode, ParseIntSign::Unsigned, ParseIntMode::DisallowEmptyString); > > if (isASCIIAlphaCaselessEqual(data[p + 1], 'o')) >- return parseInt(state, vm, data, length, p + 2, 8, errorParseMode, ParseIntSign::Unsigned, ParseIntMode::DisallowEmptyString); >+ return parseInt(exec, vm, data, length, p + 2, 8, errorParseMode, ParseIntSign::Unsigned, ParseIntMode::DisallowEmptyString); > } > > ParseIntSign sign = ParseIntSign::Unsigned; >@@ -1127,7 +1240,7 @@ JSBigInt* JSBigInt::parseInt(ExecState* state, CharType* data, unsigned length, > } > } > >- JSBigInt* result = parseInt(state, vm, data, length, p, 10, errorParseMode, sign); >+ JSBigInt* result = parseInt(exec, vm, data, length, p, 10, errorParseMode, sign); > > if (result && !result->isZero()) > result->setSign(sign == ParseIntSign::Signed); >@@ -1136,7 +1249,7 @@ JSBigInt* JSBigInt::parseInt(ExecState* state, CharType* data, unsigned length, > } > > template <typename CharType> >-JSBigInt* JSBigInt::parseInt(ExecState* state, VM& vm, CharType* data, unsigned length, unsigned startIndex, unsigned radix, ErrorParseMode errorParseMode, ParseIntSign sign, ParseIntMode parseMode) >+JSBigInt* JSBigInt::parseInt(ExecState* exec, VM& vm, CharType* data, unsigned length, unsigned startIndex, unsigned radix, ErrorParseMode errorParseMode, ParseIntSign sign, ParseIntMode parseMode) > { > ASSERT(length >= 0); > unsigned p = startIndex; >@@ -1144,9 +1257,9 @@ JSBigInt* JSBigInt::parseInt(ExecState* state, VM& vm, CharType* data, unsigned > auto scope = DECLARE_THROW_SCOPE(vm); > > if (parseMode != ParseIntMode::AllowEmptyString && startIndex == length) { >- ASSERT(state); >+ ASSERT(exec); > if (errorParseMode == ErrorParseMode::ThrowExceptions) >- throwVMError(state, scope, createSyntaxError(state, "Failed to parse String to BigInt")); >+ throwVMError(exec, scope, createSyntaxError(exec, "Failed to parse String to BigInt")); > return nullptr; > } > >@@ -1168,7 +1281,7 @@ JSBigInt* JSBigInt::parseInt(ExecState* state, VM& vm, CharType* data, unsigned > unsigned limita = 'a' + (radix - 10); > unsigned limitA = 'A' + (radix - 10); > >- JSBigInt* result = allocateFor(state, vm, radix, length - p); >+ JSBigInt* result = allocateFor(exec, vm, radix, length - p); > RETURN_IF_EXCEPTION(scope, nullptr); > > result->initialize(InitializationType::WithZero); >@@ -1191,9 +1304,9 @@ JSBigInt* JSBigInt::parseInt(ExecState* state, VM& vm, CharType* data, unsigned > if (p == length) > return result->rightTrim(vm); > >- ASSERT(state); >+ ASSERT(exec); > if (errorParseMode == ErrorParseMode::ThrowExceptions) >- throwVMError(state, scope, createSyntaxError(state, "Failed to parse String to BigInt")); >+ throwVMError(exec, scope, createSyntaxError(exec, "Failed to parse String to BigInt")); > > return nullptr; > } >diff --git a/Source/JavaScriptCore/runtime/JSBigInt.h b/Source/JavaScriptCore/runtime/JSBigInt.h >index fba5a6d..4af7a5f 100644 >--- a/Source/JavaScriptCore/runtime/JSBigInt.h >+++ b/Source/JavaScriptCore/runtime/JSBigInt.h >@@ -107,6 +107,8 @@ public: > > ComparisonResult static compareToDouble(JSBigInt* x, double y); > >+ static JSBigInt* add(VM&, JSBigInt* x, JSBigInt* y); >+ static JSBigInt* sub(VM&, JSBigInt* x, JSBigInt* y); > static JSBigInt* divide(ExecState*, JSBigInt* x, JSBigInt* y); > static JSBigInt* remainder(ExecState*, JSBigInt* x, JSBigInt* y); > static JSBigInt* unaryMinus(VM&, JSBigInt* x); >@@ -169,6 +171,8 @@ private: > JSBigInt* rightTrim(VM&); > > void inplaceMultiplyAdd(Digit multiplier, Digit part); >+ static JSBigInt* absoluteAdd(VM&, JSBigInt* x, JSBigInt* y, bool resultSign); >+ static JSBigInt* absoluteSub(VM&, JSBigInt* x, JSBigInt* y, bool resultSign); > > static size_t allocationSize(unsigned length); > static size_t offsetOfData(); >diff --git a/Source/JavaScriptCore/runtime/JSCJSValueInlines.h b/Source/JavaScriptCore/runtime/JSCJSValueInlines.h >index f9dc308..4ba9d50 100644 >--- a/Source/JavaScriptCore/runtime/JSCJSValueInlines.h >+++ b/Source/JavaScriptCore/runtime/JSCJSValueInlines.h >@@ -25,6 +25,7 @@ > > #pragma once > >+#include "CatchScope.h" > #include "Error.h" > #include "ExceptionHelpers.h" > #include "Identifier.h" >diff --git a/Source/JavaScriptCore/runtime/Operations.cpp b/Source/JavaScriptCore/runtime/Operations.cpp >index c11d905..03856fa 100644 >--- a/Source/JavaScriptCore/runtime/Operations.cpp >+++ b/Source/JavaScriptCore/runtime/Operations.cpp >@@ -23,6 +23,7 @@ > #include "Operations.h" > > #include "Error.h" >+#include "JSBigInt.h" > #include "JSCInlines.h" > #include "JSObject.h" > #include "JSString.h" >@@ -64,10 +65,19 @@ NEVER_INLINE JSValue jsAddSlowCase(CallFrame* callFrame, JSValue v1, JSValue v2) > return jsString(callFrame, p1String, asString(p2)); > } > >- double p1Number = p1.toNumber(callFrame); >+ auto leftNumeric = p1.toNumeric(callFrame); > RETURN_IF_EXCEPTION(scope, { }); >- scope.release(); >- return jsNumber(p1Number + p2.toNumber(callFrame)); >+ auto rightNumeric = p2.toNumeric(callFrame); >+ RETURN_IF_EXCEPTION(scope, { }); >+ >+ if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) { >+ if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) >+ return JSBigInt::add(vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); >+ >+ return throwTypeError(callFrame, scope, ASCIILiteral("Invalid mix of BigInt and other type in addition.")); >+ } >+ >+ return jsNumber(WTF::get<double>(leftNumeric) + WTF::get<double>(rightNumeric)); > } > > JSValue jsTypeStringForValue(VM& vm, JSGlobalObject* globalObject, JSValue v) >diff --git a/Source/JavaScriptCore/runtime/Operations.h b/Source/JavaScriptCore/runtime/Operations.h >index f95b9d0..2647c97 100644 >--- a/Source/JavaScriptCore/runtime/Operations.h >+++ b/Source/JavaScriptCore/runtime/Operations.h >@@ -348,6 +348,26 @@ ALWAYS_INLINE JSValue jsAdd(CallFrame* callFrame, JSValue v1, JSValue v2) > return jsAddSlowCase(callFrame, v1, v2); > } > >+ALWAYS_INLINE JSValue jsSub(ExecState* state, JSValue v1, JSValue v2) >+{ >+ VM& vm = state->vm(); >+ auto scope = DECLARE_THROW_SCOPE(vm); >+ >+ auto leftNumeric = v1.toNumeric(state); >+ RETURN_IF_EXCEPTION(scope, { }); >+ auto rightNumeric = v2.toNumeric(state); >+ RETURN_IF_EXCEPTION(scope, { }); >+ >+ if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) { >+ if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) >+ return JSBigInt::sub(vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); >+ >+ return throwTypeError(state, scope, ASCIILiteral("Invalid mix of BigInt and other type in subtraction.")); >+ } >+ >+ return jsNumber(WTF::get<double>(leftNumeric) - WTF::get<double>(rightNumeric)); >+} >+ > ALWAYS_INLINE JSValue jsMul(ExecState* state, JSValue v1, JSValue v2) > { > VM& vm = state->vm();
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 179002
:
331884
|
331885
|
331886
|
331887
|
331888
|
332079
|
332085
|
332096
|
332097
|
332101
|
332106
|
332144
|
332146
|
332195
|
332317
|
332318
|
332320
|
341725
|
341759
|
341815
|
341860