Skip to content

Commit

Permalink
[ESNext][BigInt] Implement support for addition operations
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=179002

Reviewed by Yusuke Suzuki.

JSTests:

* 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.

Source/JavaScriptCore:

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):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@232449 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
[email protected] committed Jun 3, 2018
1 parent 25ab565 commit 5810702
Show file tree
Hide file tree
Showing 25 changed files with 1,296 additions and 69 deletions.
24 changes: 24 additions & 0 deletions JSTests/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
2018-06-02 Caio Lima <[email protected]>

[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-06-02 Commit Queue <[email protected]>

Unreviewed, rolling out r232439.
Expand Down
35 changes: 35 additions & 0 deletions JSTests/bigIntTests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
23 changes: 23 additions & 0 deletions JSTests/stress/addition-order-evaluation.js
Original file line number Diff line number Diff line change
@@ -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);
}

37 changes: 37 additions & 0 deletions JSTests/stress/big-int-add-wrapped-value.js
Original file line number Diff line number Diff line change
@@ -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");

170 changes: 170 additions & 0 deletions JSTests/stress/big-int-addition-basic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
//@ 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);
testAdd(18446744073709551617n, -18446744073709551616n, 1n);

19 changes: 19 additions & 0 deletions JSTests/stress/big-int-addition-jit.js
Original file line number Diff line number Diff line change
@@ -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);
}

14 changes: 14 additions & 0 deletions JSTests/stress/big-int-addition-memory-stress.js
Original file line number Diff line number Diff line change
@@ -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);

25 changes: 25 additions & 0 deletions JSTests/stress/big-int-addition-string-coercion.js
Original file line number Diff line number Diff line change
@@ -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]");

Loading

0 comments on commit 5810702

Please sign in to comment.