Unreviewed, rolling out r231131.
https://bugs.webkit.org/show_bug.cgi?id=185112
It is breaking Debug build due to unchecked exception
(Requested by caiolima on #webkit).
Reverted changeset:
"[ESNext][BigInt] Implement support for "*" operation"
https://bugs.webkit.org/show_bug.cgi?id=183721
https://trac.webkit.org/changeset/231131
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@231133 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog
index 1bdb91c..1392a0d 100644
--- a/JSTests/ChangeLog
+++ b/JSTests/ChangeLog
@@ -1,3 +1,17 @@
+2018-04-28 Commit Queue <commit-queue@webkit.org>
+
+ Unreviewed, rolling out r231131.
+ https://bugs.webkit.org/show_bug.cgi?id=185112
+
+ It is breaking Debug build due to unchecked exception
+ (Requested by caiolima on #webkit).
+
+ Reverted changeset:
+
+ "[ESNext][BigInt] Implement support for "*" operation"
+ https://bugs.webkit.org/show_bug.cgi?id=183721
+ https://trac.webkit.org/changeset/231131
+
2018-04-27 Caio Lima <ticaiolima@gmail.com>
[ESNext][BigInt] Implement support for "*" operation
diff --git a/JSTests/bigIntTests.yaml b/JSTests/bigIntTests.yaml
index e947dc2..7ae22cb 100644
--- a/JSTests/bigIntTests.yaml
+++ b/JSTests/bigIntTests.yaml
@@ -97,24 +97,3 @@
- path: stress/big-int-to-string.js
cmd: runBigIntEnabled
-- path: stress/big-int-mul-jit.js
- cmd: runBigIntEnabled
-
-- path: stress/big-int-mul-to-primitive-precedence.js
- cmd: runBigIntEnabled
-
-- path: stress/big-int-mul-to-primitive.js
- cmd: runBigIntEnabled
-
-- path: stress/big-int-mul-type-error.js
- cmd: runBigIntEnabled
-
-- path: stress/big-int-mul-wrapped-value.js
- cmd: runBigIntEnabled
-
-- path: stress/big-int-multiplication.js
- cmd: runBigIntEnabled
-
-- path: stress/big-int-multiply-memory-stress.js
- cmd: runBigIntEnabled
-
diff --git a/JSTests/stress/big-int-mul-jit.js b/JSTests/stress/big-int-mul-jit.js
deleted file mode 100644
index 0cbede3..0000000
--- a/JSTests/stress/big-int-mul-jit.js
+++ /dev/null
@@ -1,19 +0,0 @@
-//@ runBigIntEnabled
-
-let assert = {
- sameValue: function(i, e, m) {
- if (i !== e)
- throw new Error(m);
- }
-}
-
-function bigIntMul(x, y) {
- return x * y;
-}
-noInline(bigIntMul);
-
-for (let i = 0; i < 10000; i++) {
- let r = bigIntMul(3n, 10n);
- assert.sameValue(r, 30n, 3n + " * " + 10n + " = " + r);
-}
-
diff --git a/JSTests/stress/big-int-mul-to-primitive-precedence.js b/JSTests/stress/big-int-mul-to-primitive-precedence.js
deleted file mode 100644
index 7149a19..0000000
--- a/JSTests/stress/big-int-mul-to-primitive-precedence.js
+++ /dev/null
@@ -1,39 +0,0 @@
-//@ runBigIntEnabled
-
-assert = {
- sameValue: function (input, expected, message) {
- if (input !== expected)
- throw new Error(message);
- }
-};
-
-function testMul(x, y, z, message) {
- assert.sameValue(x * y, z, message);
- assert.sameValue(y * x, z, message);
-}
-
-testMul(Object(2n), 1n, 2n, "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");
- }
-};
-testMul(o, 1n, 2n, "ToPrimitive: @@toPrimitive");
-
-o = {
- valueOf: function() {
- return 2n;
- },
- toString: function () {
- throw new Error("Should never execute it");
- }
-};
-testMul(o, 1n, 2n, "ToPrimitive: valueOf");
-
diff --git a/JSTests/stress/big-int-mul-to-primitive.js b/JSTests/stress/big-int-mul-to-primitive.js
deleted file mode 100644
index 642e2e8..0000000
--- a/JSTests/stress/big-int-mul-to-primitive.js
+++ /dev/null
@@ -1,35 +0,0 @@
-//@ 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 testMul(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; }
-}
-
-testMul(500000000000438n, o, 150000000000131400000000000000n);
-
-o.valueOf = function () {
- throw new Error("Should never execute it");
-};
-
-testMul(700000000000438n, o, 210000000000131400000000000000n);
-
-o.toString = function () {
- throw new Error("Should never execute it");
-};
-
-testMul(700000000000438n, o, 210000000000131400000000000000n);
-
diff --git a/JSTests/stress/big-int-mul-type-error.js b/JSTests/stress/big-int-mul-type-error.js
deleted file mode 100644
index b517845..0000000
--- a/JSTests/stress/big-int-mul-type-error.js
+++ /dev/null
@@ -1,106 +0,0 @@
-//@ 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, "foo", "BigInt * String");
-assertThrowTypeError("bar", 18757382984821n, "String * BigInt");
-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-mul-wrapped-value.js b/JSTests/stress/big-int-mul-wrapped-value.js
deleted file mode 100644
index b673d8a..0000000
--- a/JSTests/stress/big-int-mul-wrapped-value.js
+++ /dev/null
@@ -1,37 +0,0 @@
-//@ runBigIntEnabled
-
-assert = {
- sameValue: function (input, expected, message) {
- if (input !== expected)
- throw new Error(message);
- }
-};
-
-function testMul(x, y, z, message) {
- assert.sameValue(x * y, z, message);
- assert.sameValue(y * x, z, message);
-}
-
-testMul(Object(2n), 1n, 2n, "ToPrimitive: unbox object with internal slot");
-
-let o = {
- [Symbol.toPrimitive]: function() {
- return 2n;
- }
-};
-testMul(o, 1n, 2n, "ToPrimitive: @@toPrimitive");
-
-o = {
- valueOf: function() {
- return 2n;
- }
-};
-testMul(o, 1n, 2n, "ToPrimitive: valueOf");
-
-o = {
- toString: function() {
- return 2n;
- }
-}
-testMul(o, 1n, 2n, "ToPrimitive: toString");
-
diff --git a/JSTests/stress/big-int-multiplication.js b/JSTests/stress/big-int-multiplication.js
deleted file mode 100644
index 3ecd636..0000000
--- a/JSTests/stress/big-int-multiplication.js
+++ /dev/null
@@ -1,83 +0,0 @@
-//@ runBigIntEnabled
-
-// Copyright (C) 2017 Robin Templeton. All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-assert = {
- sameValue: function (input, expected, message) {
- if (input !== expected)
- throw new Error(message);
- }
-};
-
-function testMul(x, y, z) {
- assert.sameValue(x * y, z, x + " * " + y + " = " + z);
- assert.sameValue(y * x, z, y + " * " + x + " = " + z);
-}
-
-testMul(0xFEDCBA9876543210n, 0xFEDCBA9876543210n, 0xFDBAC097C8DC5ACCDEEC6CD7A44A4100n);
-testMul(0xFEDCBA9876543210n, 0xFEDCBA98n, 0xFDBAC097530ECA86541D5980n);
-testMul(0xFEDCBA9876543210n, 0x1234n, 0x121F49F49F49F49F4B40n);
-testMul(0xFEDCBA9876543210n, 0x3n, 0x2FC962FC962FC9630n);
-testMul(0xFEDCBA9876543210n, 0x2n, 0x1FDB97530ECA86420n);
-testMul(0xFEDCBA9876543210n, 0x1n, 0xFEDCBA9876543210n);
-testMul(0xFEDCBA9876543210n, 0x0n, 0x0n);
-testMul(0xFEDCBA9876543210n, BigInt("-1"), BigInt("-18364758544493064720"));
-testMul(0xFEDCBA9876543210n, BigInt("-2"), BigInt("-36729517088986129440"));
-testMul(0xFEDCBA9876543210n, BigInt("-3"), BigInt("-55094275633479194160"));
-testMul(0xFEDCBA9876543210n, BigInt("-4660"), BigInt("-85579774817337681595200"));
-testMul(0xFEDCBA9876543210n, BigInt("-4275878551"), BigInt("-78525477154691874604502820720"));
-testMul(0xFEDCBA987654320Fn, 0xFEDCBA987654320Fn, 0xFDBAC097C8DC5ACAE132F7A6B7A1DCE1n);
-testMul(0xFEDCBA987654320Fn, 0xFEDCBA97n, 0xFDBAC09654320FECDEEC6CD9n);
-testMul(0xFEDCBA987654320Fn, 0x3n, 0x2FC962FC962FC962Dn);
-testMul(0xFEDCBA987654320Fn, 0x2n, 0x1FDB97530ECA8641En);
-testMul(0xFEDCBA987654320Fn, 0x1n, 0xFEDCBA987654320Fn);
-testMul(0xFEDCBA987654320Fn, 0x0n, 0x0n);
-testMul(0xFEDCBA987654320Fn, BigInt("-1"), BigInt("-18364758544493064719"));
-testMul(0xFEDCBA987654320Fn, BigInt("-2"), BigInt("-36729517088986129438"));
-testMul(0xFEDCBA987654320Fn, BigInt("-3"), BigInt("-55094275633479194157"));
-testMul(0xFEDCBA987654320Fn, BigInt("-4275878551"), BigInt("-78525477154691874600226942169"));
-testMul(0xFEDCBA987654320Fn, BigInt("-18364758544493064720"), BigInt("-337264356397531028976608289633615613680"));
-testMul(0xFEDCBA98n, 0xFEDCBA98n, 0xFDBAC096DD413A40n);
-testMul(0xFEDCBA98n, 0x1234n, 0x121F49F496E0n);
-testMul(0xFEDCBA98n, 0x3n, 0x2FC962FC8n);
-testMul(0xFEDCBA98n, 0x2n, 0x1FDB97530n);
-testMul(0xFEDCBA98n, 0x1n, 0xFEDCBA98n);
-testMul(0xFEDCBA98n, 0x0n, 0x0n);
-testMul(0xFEDCBA98n, BigInt("-1"), BigInt("-4275878552"));
-testMul(0xFEDCBA98n, BigInt("-2"), BigInt("-8551757104"));
-testMul(0xFEDCBA98n, BigInt("-3"), BigInt("-12827635656"));
-testMul(0xFEDCBA98n, BigInt("-4275878551"), BigInt("-18283137387177738152"));
-testMul(0xFEDCBA98n, BigInt("-18364758544493064720"), BigInt("-78525477173056633148995885440"));
-testMul(0x3n, 0x3n, 0x9n);
-testMul(0x3n, 0x2n, 0x6n);
-testMul(0x3n, 0x1n, 0x3n);
-testMul(0x3n, 0x0n, 0x0n);
-testMul(0x3n, BigInt("-1"), BigInt("-3"));
-testMul(0x3n, BigInt("-2"), BigInt("-6"));
-testMul(0x3n, BigInt("-3"), BigInt("-9"));
-testMul(0x3n, BigInt("-4660"), BigInt("-13980"));
-testMul(0x3n, BigInt("-4275878552"), BigInt("-12827635656"));
-testMul(0x3n, BigInt("-18364758544493064720"), BigInt("-55094275633479194160"));
-testMul(0x0n, 0x0n, 0x0n);
-testMul(0x0n, BigInt("-1"), 0x0n);
-testMul(0x0n, BigInt("-2"), 0x0n);
-testMul(0x0n, BigInt("-3"), 0x0n);
-testMul(0x0n, BigInt("-4275878551"), 0x0n);
-testMul(0x0n, BigInt("-18364758544493064719"), 0x0n);
-testMul(BigInt("-1"), BigInt("-1"), 0x1n);
-testMul(BigInt("-1"), BigInt("-2"), 0x2n);
-testMul(BigInt("-1"), BigInt("-3"), 0x3n);
-testMul(BigInt("-1"), BigInt("-4660"), 0x1234n);
-testMul(BigInt("-1"), BigInt("-4275878551"), 0xFEDCBA97n);
-testMul(BigInt("-1"), BigInt("-4275878552"), 0xFEDCBA98n);
-testMul(BigInt("-1"), BigInt("-18364758544493064719"), 0xFEDCBA987654320Fn);
-testMul(BigInt("-1"), BigInt("-18364758544493064720"), 0xFEDCBA9876543210n);
-testMul(BigInt("-3"), BigInt("-3"), 0x9n);
-testMul(BigInt("-3"), BigInt("-4660"), 0x369Cn);
-testMul(BigInt("-3"), BigInt("-4275878551"), 0x2FC962FC5n);
-testMul(BigInt("-3"), BigInt("-4275878552"), 0x2FC962FC8n);
-testMul(BigInt("-3"), BigInt("-18364758544493064719"), 0x2FC962FC962FC962Dn);
-testMul(BigInt("-3"), BigInt("-18364758544493064720"), 0x2FC962FC962FC9630n);
-testMul(BigInt("-18364758544493064720"), BigInt("-18364758544493064720"), 0xFDBAC097C8DC5ACCDEEC6CD7A44A4100n);
-
diff --git a/JSTests/stress/big-int-multiply-memory-stress.js b/JSTests/stress/big-int-multiply-memory-stress.js
deleted file mode 100644
index 1abaa7e..0000000
--- a/JSTests/stress/big-int-multiply-memory-stress.js
+++ /dev/null
@@ -1,15 +0,0 @@
-//@ runBigIntEnabled
-
-function assert(a) {
- if (!a)
- throw new Error("Bad assertion");
-}
-
-let a = 0n;
-let b = 1n;
-for (let i = 0; i < 1000000; i++) {
- a = b * 30n;
-}
-
-assert(a === 30n);
-
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index b3474d0..6a1191d 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,17 @@
+2018-04-28 Commit Queue <commit-queue@webkit.org>
+
+ Unreviewed, rolling out r231131.
+ https://bugs.webkit.org/show_bug.cgi?id=185112
+
+ It is breaking Debug build due to unchecked exception
+ (Requested by caiolima on #webkit).
+
+ Reverted changeset:
+
+ "[ESNext][BigInt] Implement support for "*" operation"
+ https://bugs.webkit.org/show_bug.cgi?id=183721
+ https://trac.webkit.org/changeset/231131
+
2018-04-27 Caio Lima <ticaiolima@gmail.com>
[ESNext][BigInt] Implement support for "*" operation
diff --git a/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp b/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
index e4650ac..cee6562 100644
--- a/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
@@ -146,14 +146,14 @@
JSValue child2Constant = m_state.forNode(node->child2().node()).value();
// FIXME: Revisit this condition when introducing BigInt to JSC.
- auto isNonStringOrBigIntCellConstant = [] (JSValue value) {
- return value && value.isCell() && !value.isString() && !value.isBigInt();
+ auto isNonStringCellConstant = [] (JSValue value) {
+ return value && value.isCell() && !value.isString();
};
- if (isNonStringOrBigIntCellConstant(child1Constant)) {
+ if (isNonStringCellConstant(child1Constant)) {
node->convertToCompareEqPtr(m_graph.freezeStrong(child1Constant.asCell()), node->child2());
changed = true;
- } else if (isNonStringOrBigIntCellConstant(child2Constant)) {
+ } else if (isNonStringCellConstant(child2Constant)) {
node->convertToCompareEqPtr(m_graph.freezeStrong(child2Constant.asCell()), node->child1());
changed = true;
}
diff --git a/Source/JavaScriptCore/jit/JITOperations.cpp b/Source/JavaScriptCore/jit/JITOperations.cpp
index 62fc1b0..365bb73 100644
--- a/Source/JavaScriptCore/jit/JITOperations.cpp
+++ b/Source/JavaScriptCore/jit/JITOperations.cpp
@@ -2554,23 +2554,34 @@
return JSValue::encode(result);
}
-ALWAYS_INLINE static EncodedJSValue unprofiledMul(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
+ALWAYS_INLINE static EncodedJSValue unprofiledMul(VM& vm, ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
{
+ auto scope = DECLARE_THROW_SCOPE(vm);
JSValue op1 = JSValue::decode(encodedOp1);
JSValue op2 = JSValue::decode(encodedOp2);
- return JSValue::encode(jsMul(exec, op1, op2));
+ double a = op1.toNumber(exec);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ scope.release();
+ double b = op2.toNumber(exec);
+ return JSValue::encode(jsNumber(a * b));
}
-ALWAYS_INLINE static EncodedJSValue profiledMul(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true)
+ALWAYS_INLINE static EncodedJSValue profiledMul(VM& vm, 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);
- JSValue result = jsMul(exec, 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);
arithProfile.observeResult(result);
return JSValue::encode(result);
}
@@ -2580,7 +2591,7 @@
VM* vm = &exec->vm();
NativeCallFrameTracer tracer(vm, exec);
- return unprofiledMul(exec, encodedOp1, encodedOp2);
+ return unprofiledMul(*vm, exec, encodedOp1, encodedOp2);
}
EncodedJSValue JIT_OPERATION operationValueMulNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*)
@@ -2588,7 +2599,7 @@
VM* vm = &exec->vm();
NativeCallFrameTracer tracer(vm, exec);
- return unprofiledMul(exec, encodedOp1, encodedOp2);
+ return unprofiledMul(*vm, exec, encodedOp1, encodedOp2);
}
EncodedJSValue JIT_OPERATION operationValueMulOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC* mulIC)
@@ -2605,7 +2616,7 @@
exec->codeBlock()->dumpMathICStats();
#endif
- return unprofiledMul(exec, encodedOp1, encodedOp2);
+ return unprofiledMul(*vm, exec, encodedOp1, encodedOp2);
}
EncodedJSValue JIT_OPERATION operationValueMulProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)
@@ -2614,7 +2625,7 @@
NativeCallFrameTracer tracer(vm, exec);
ASSERT(arithProfile);
- return profiledMul(exec, encodedOp1, encodedOp2, *arithProfile);
+ return profiledMul(*vm, exec, encodedOp1, encodedOp2, *arithProfile);
}
EncodedJSValue JIT_OPERATION operationValueMulProfiledOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC* mulIC)
@@ -2632,7 +2643,7 @@
exec->codeBlock()->dumpMathICStats();
#endif
- return profiledMul(exec, encodedOp1, encodedOp2, *arithProfile, false);
+ return profiledMul(*vm, exec, encodedOp1, encodedOp2, *arithProfile, false);
}
EncodedJSValue JIT_OPERATION operationValueMulProfiledNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC* mulIC)
@@ -2642,7 +2653,7 @@
ArithProfile* arithProfile = mulIC->arithProfile();
ASSERT(arithProfile);
- return profiledMul(exec, encodedOp1, encodedOp2, *arithProfile);
+ return profiledMul(*vm, exec, encodedOp1, encodedOp2, *arithProfile);
}
ALWAYS_INLINE static EncodedJSValue unprofiledNegate(ExecState* exec, EncodedJSValue encodedOperand)
diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
index df8fe73d..e6c1a44 100644
--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
@@ -486,24 +486,10 @@
BEGIN();
JSValue left = OP_C(2).jsValue();
JSValue right = OP_C(3).jsValue();
- JSValue leftPrimitive = left.toPrimitive(exec, PreferNumber);
- CHECK_EXCEPTION();
- JSValue rightPrimitive = right.toPrimitive(exec, PreferNumber);
- CHECK_EXCEPTION();
-
- if (leftPrimitive.isBigInt() || rightPrimitive.isBigInt()) {
- if (leftPrimitive.isBigInt() && rightPrimitive.isBigInt()) {
- JSValue result(JSBigInt::multiply(exec, asBigInt(leftPrimitive), asBigInt(rightPrimitive)));
- RETURN_WITH_PROFILING(result, {
- updateArithProfileForBinaryArithOp(exec, pc, result, left, right);
- });
- }
-
- THROW(createTypeError(exec, "Invalid mix of BigInt and other type in multiplication."));
- }
-
- double a = leftPrimitive.toNumber(exec);
- double b = rightPrimitive.toNumber(exec);
+ double a = left.toNumber(exec);
+ if (UNLIKELY(throwScope.exception()))
+ RETURN(JSValue());
+ double b = right.toNumber(exec);
JSValue result = jsNumber(a * b);
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 9197b9a..c51c8b2 100644
--- a/Source/JavaScriptCore/runtime/JSBigInt.cpp
+++ b/Source/JavaScriptCore/runtime/JSBigInt.cpp
@@ -69,7 +69,7 @@
Base::visitChildren(thisObject, visitor);
}
-JSBigInt::JSBigInt(VM& vm, Structure* structure, unsigned length)
+JSBigInt::JSBigInt(VM& vm, Structure* structure, int length)
: Base(vm, structure)
, m_length(length)
{ }
@@ -93,13 +93,13 @@
return zeroBigInt;
}
-size_t JSBigInt::allocationSize(unsigned length)
+size_t JSBigInt::allocationSize(int length)
{
size_t sizeWithPadding = WTF::roundUpToMultipleOf<sizeof(size_t)>(sizeof(JSBigInt));
return sizeWithPadding + length * sizeof(Digit);
}
-JSBigInt* JSBigInt::createWithLength(VM& vm, unsigned length)
+JSBigInt* JSBigInt::createWithLength(VM& vm, int length)
{
JSBigInt* bigInt = new (NotNull, allocateCell<JSBigInt>(vm.heap, allocationSize(length))) JSBigInt(vm, vm.bigIntStructure.get(), length);
bigInt->finishCreation(vm);
@@ -223,7 +223,7 @@
return parseInt(state, vm, s.characters16(), s.length(), 0, radix, false);
}
-String JSBigInt::toString(ExecState& state, unsigned radix)
+String JSBigInt::toString(ExecState& state, int radix)
{
if (this->isZero())
return state.vm().smallStrings.singleCharacterStringRep('0');
@@ -246,26 +246,6 @@
internalMultiplyAdd(this, factor, summand, length(), this);
}
-JSBigInt* JSBigInt::multiply(ExecState* state, JSBigInt* x, JSBigInt* y)
-{
- VM& vm = state->vm();
-
- if (x->isZero())
- return x;
- if (y->isZero())
- return y;
-
- unsigned resultLength = x->length() + y->length();
- JSBigInt* result = JSBigInt::createWithLength(vm, resultLength);
- result->initialize(InitializationType::WithZero);
-
- for (unsigned i = 0; i < x->length(); i++)
- multiplyAccumulate(y, x->digit(i), result, i);
-
- result->setSign(x->sign() != y->sign());
- return result->rightTrim(vm);
-}
-
#if USE(JSVALUE32_64)
#define HAVE_TWO_DIGIT 1
typedef uint64_t TwoDigit;
@@ -398,9 +378,9 @@
static const Digit kHalfDigitBase = 1ull << halfDigitBits;
// Adapted from Warren, Hacker's Delight, p. 152.
#if USE(JSVALUE64)
- unsigned s = clz64(divisor);
+ int s = clz64(divisor);
#else
- unsigned s = clz32(divisor);
+ int s = clz32(divisor);
#endif
divisor <<= s;
@@ -443,14 +423,14 @@
// Multiplies {source} with {factor} and adds {summand} to the result.
// {result} and {source} may be the same BigInt for inplace modification.
-void JSBigInt::internalMultiplyAdd(JSBigInt* source, Digit factor, Digit summand, unsigned n, JSBigInt* result)
+void JSBigInt::internalMultiplyAdd(JSBigInt* source, Digit factor, Digit summand, int n, JSBigInt* result)
{
ASSERT(source->length() >= n);
ASSERT(result->length() >= n);
Digit carry = summand;
Digit high = 0;
- for (unsigned i = 0; i < n; i++) {
+ for (int i = 0; i < n; i++) {
Digit current = source->digit(i);
Digit newCarry = 0;
@@ -478,49 +458,6 @@
ASSERT(!(carry + high));
}
-// Multiplies {multiplicand} with {multiplier} and adds the result to
-// {accumulator}, starting at {accumulatorIndex} for the least-significant
-// digit.
-// Callers must ensure that {accumulator} is big enough to hold the result.
-void JSBigInt::multiplyAccumulate(JSBigInt* multiplicand, Digit multiplier, JSBigInt* accumulator, unsigned accumulatorIndex)
-{
- ASSERT(accumulator->length() > multiplicand->length() + accumulatorIndex);
- if (!multiplier)
- return;
-
- Digit carry = 0;
- Digit high = 0;
- for (unsigned i = 0; i < multiplicand->length(); i++, accumulatorIndex++) {
- Digit acc = accumulator->digit(accumulatorIndex);
- Digit newCarry = 0;
-
- // Add last round's carryovers.
- acc = digitAdd(acc, high, newCarry);
- acc = digitAdd(acc, carry, newCarry);
-
- // Compute this round's multiplication.
- Digit multiplicandDigit = multiplicand->digit(i);
- Digit low = digitMul(multiplier, multiplicandDigit, high);
- acc = digitAdd(acc, low, newCarry);
-
- // Store result and prepare for next round.
- accumulator->setDigit(accumulatorIndex, acc);
- carry = newCarry;
- }
-
- while (carry || high) {
- ASSERT(accumulatorIndex < accumulator->length());
- Digit acc = accumulator->digit(accumulatorIndex);
- Digit newCarry = 0;
- acc = digitAdd(acc, high, newCarry);
- high = 0;
- acc = digitAdd(acc, carry, newCarry);
- accumulator->setDigit(accumulatorIndex, acc);
- carry = newCarry;
- accumulatorIndex++;
- }
-}
-
bool JSBigInt::equals(JSBigInt* x, JSBigInt* y)
{
if (x->sign() != y->sign())
@@ -529,7 +466,7 @@
if (x->length() != y->length())
return false;
- for (unsigned i = 0; i < x->length(); i++) {
+ for (int i = 0; i < x->length(); i++) {
if (x->digit(i) != y->digit(i))
return false;
}
@@ -557,7 +494,7 @@
return;
}
- unsigned length = x->length();
+ int length = x->length();
if (quotient != nullptr) {
if (*quotient == nullptr)
*quotient = JSBigInt::createWithLength(vm, length);
@@ -584,14 +521,14 @@
162, 163, 165, 166, // 33..36
};
-static const unsigned bitsPerCharTableShift = 5;
+static const int bitsPerCharTableShift = 5;
static const size_t bitsPerCharTableMultiplier = 1u << bitsPerCharTableShift;
// Compute (an overapproximation of) the length of the resulting string:
// Divide bit length of the BigInt by bits representable per character.
-uint64_t JSBigInt::calculateMaximumCharactersRequired(unsigned length, unsigned radix, Digit lastDigit, bool sign)
+uint64_t JSBigInt::calculateMaximumCharactersRequired(int length, int radix, Digit lastDigit, bool sign)
{
- unsigned leadingZeros;
+ int leadingZeros;
if (sizeof(lastDigit) == 8)
leadingZeros = clz64(lastDigit);
else
@@ -619,7 +556,7 @@
return maximumCharactersRequired;
}
-String JSBigInt::toStringGeneric(ExecState& state, JSBigInt* x, unsigned radix)
+String JSBigInt::toStringGeneric(ExecState& state, JSBigInt* x, int radix)
{
// FIXME: [JSC] Revisit usage of StringVector into JSBigInt::toString
// https://bugs.webkit.org/show_bug.cgi?id=18067
@@ -628,7 +565,7 @@
ASSERT(radix >= 2 && radix <= 36);
ASSERT(!x->isZero());
- unsigned length = x->length();
+ int length = x->length();
bool sign = x->sign();
uint8_t maxBitsPerChar = maxBitsPerCharTable[radix];
@@ -644,12 +581,12 @@
if (length == 1)
lastDigit = x->digit(0);
else {
- unsigned chunkChars = digitBits * bitsPerCharTableMultiplier / maxBitsPerChar;
+ int chunkChars = digitBits * bitsPerCharTableMultiplier / maxBitsPerChar;
Digit chunkDivisor = digitPow(radix, chunkChars);
// By construction of chunkChars, there can't have been overflow.
ASSERT(chunkDivisor);
- unsigned nonZeroDigit = length - 1;
+ int nonZeroDigit = length - 1;
ASSERT(x->digit(nonZeroDigit));
// {rest} holds the part of the BigInt that we haven't looked at yet.
@@ -665,7 +602,7 @@
ASSERT(rest);
dividend = &rest;
- for (unsigned i = 0; i < chunkChars; i++) {
+ for (int i = 0; i < chunkChars; i++) {
resultString.append(radixDigits[chunk % radix]);
chunk /= radix;
}
@@ -690,7 +627,7 @@
ASSERT(resultString.size() <= static_cast<size_t>(maximumCharactersRequired));
// Remove leading zeroes.
- unsigned newSizeNoLeadingZeroes = resultString.size();
+ int newSizeNoLeadingZeroes = resultString.size();
while (newSizeNoLeadingZeroes > 1 && resultString[newSizeNoLeadingZeroes - 1] == '0')
newSizeNoLeadingZeroes--;
@@ -709,16 +646,14 @@
if (isZero())
return this;
- ASSERT(m_length);
-
int nonZeroIndex = m_length - 1;
while (nonZeroIndex >= 0 && !digit(nonZeroIndex))
nonZeroIndex--;
- if (nonZeroIndex == static_cast<int>(m_length - 1))
+ if (nonZeroIndex == m_length - 1)
return this;
- unsigned newLength = nonZeroIndex + 1;
+ int newLength = nonZeroIndex + 1;
JSBigInt* trimmedBigInt = createWithLength(vm, newLength);
RELEASE_ASSERT(trimmedBigInt);
std::copy(dataStorage(), dataStorage() + newLength, trimmedBigInt->dataStorage());
@@ -728,14 +663,14 @@
return trimmedBigInt;
}
-JSBigInt* JSBigInt::allocateFor(ExecState* state, VM& vm, unsigned radix, unsigned charcount)
+JSBigInt* JSBigInt::allocateFor(ExecState* state, VM& vm, int radix, int charcount)
{
ASSERT(2 <= radix && radix <= 36);
ASSERT(charcount >= 0);
size_t bitsPerChar = maxBitsPerCharTable[radix];
size_t chars = charcount;
- const unsigned roundup = bitsPerCharTableMultiplier - 1;
+ const int roundup = bitsPerCharTableMultiplier - 1;
if (chars <= (std::numeric_limits<size_t>::max() - roundup) / bitsPerChar) {
size_t bitsMin = bitsPerChar * chars;
@@ -743,7 +678,7 @@
bitsMin = (bitsMin + roundup) >> bitsPerCharTableShift;
if (bitsMin <= static_cast<size_t>(maxInt)) {
// Divide by kDigitsBits, rounding up.
- unsigned length = (bitsMin + digitBits - 1) / digitBits;
+ int length = (static_cast<int>(bitsMin) + digitBits - 1) / digitBits;
if (length <= maxLength) {
JSBigInt* result = JSBigInt::createWithLength(vm, length);
return result;
@@ -784,11 +719,11 @@
}
template <typename CharType>
-JSBigInt* JSBigInt::parseInt(ExecState* state, CharType* data, unsigned length)
+JSBigInt* JSBigInt::parseInt(ExecState* state, CharType* data, int length)
{
VM& vm = state->vm();
- unsigned p = 0;
+ int p = 0;
while (p < length && isStrWhiteSpace(data[p]))
++p;
@@ -823,10 +758,10 @@
}
template <typename CharType>
-JSBigInt* JSBigInt::parseInt(ExecState* state, VM& vm, CharType* data, unsigned length, unsigned startIndex, unsigned radix, bool allowEmptyString)
+JSBigInt* JSBigInt::parseInt(ExecState* state, VM& vm, CharType* data, int length, int startIndex, int radix, bool allowEmptyString)
{
ASSERT(length >= 0);
- unsigned p = startIndex;
+ int p = startIndex;
auto scope = DECLARE_THROW_SCOPE(vm);
@@ -842,7 +777,7 @@
int endIndex = length - 1;
// Removing trailing spaces
- while (endIndex >= static_cast<int>(p) && isStrWhiteSpace(data[endIndex]))
+ while (endIndex >= p && isStrWhiteSpace(data[endIndex]))
--endIndex;
length = endIndex + 1;
@@ -850,16 +785,16 @@
if (p == length)
return createZero(vm);
- unsigned limit0 = '0' + (radix < 10 ? radix : 10);
- unsigned limita = 'a' + (radix - 10);
- unsigned limitA = 'A' + (radix - 10);
+ int limit0 = '0' + (radix < 10 ? radix : 10);
+ int limita = 'a' + (radix - 10);
+ int limitA = 'A' + (radix - 10);
JSBigInt* result = allocateFor(state, vm, radix, length - p);
RETURN_IF_EXCEPTION(scope, nullptr);
result->initialize(InitializationType::WithZero);
- for (unsigned i = p; i < length; i++, p++) {
+ for (int i = p; i < length; i++, p++) {
uint32_t digit;
if (data[i] >= '0' && data[i] < limit0)
digit = data[i] - '0';
@@ -887,13 +822,13 @@
return reinterpret_cast<Digit*>(reinterpret_cast<char*>(this) + offsetOfData());
}
-JSBigInt::Digit JSBigInt::digit(unsigned n)
+JSBigInt::Digit JSBigInt::digit(int n)
{
ASSERT(n >= 0 && n < length());
return dataStorage()[n];
}
-void JSBigInt::setDigit(unsigned n, Digit value)
+void JSBigInt::setDigit(int n, Digit value)
{
ASSERT(n >= 0 && n < length());
dataStorage()[n] = value;
diff --git a/Source/JavaScriptCore/runtime/JSBigInt.h b/Source/JavaScriptCore/runtime/JSBigInt.h
index eb12c00..298c348 100644
--- a/Source/JavaScriptCore/runtime/JSBigInt.h
+++ b/Source/JavaScriptCore/runtime/JSBigInt.h
@@ -41,7 +41,7 @@
public:
- JSBigInt(VM&, Structure*, unsigned length);
+ JSBigInt(VM&, Structure*, int length);
enum class InitializationType { None, WithZero };
void initialize(InitializationType);
@@ -49,11 +49,12 @@
static void visitChildren(JSCell*, SlotVisitor&);
static size_t estimatedSize(JSCell*);
- static size_t allocationSize(unsigned length);
+ static size_t allocationSize(int length);
static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
+
static JSBigInt* createZero(VM&);
- static JSBigInt* createWithLength(VM&, unsigned length);
+ static JSBigInt* createWithLength(VM&, int length);
static JSBigInt* createFrom(VM&, int32_t value);
static JSBigInt* createFrom(VM&, uint32_t value);
@@ -69,14 +70,14 @@
void setSign(bool sign) { m_sign = sign; }
bool sign() const { return m_sign; }
- void setLength(unsigned length) { m_length = length; }
- unsigned length() const { return m_length; }
+ void setLength(int length) { m_length = length; }
+ int length() const { return m_length; }
static JSBigInt* parseInt(ExecState*, VM&, StringView, uint8_t radix);
static JSBigInt* parseInt(ExecState*, StringView);
std::optional<uint8_t> singleDigitValueForString();
- String toString(ExecState&, unsigned radix);
+ String toString(ExecState&, int radix);
JS_EXPORT_PRIVATE static bool equals(JSBigInt*, JSBigInt*);
@@ -84,14 +85,12 @@
double toNumber(ExecState*) const;
JSObject* toObject(ExecState*, JSGlobalObject*) const;
-
- static JSBigInt* multiply(ExecState*, JSBigInt* x, JSBigInt* y);
private:
using Digit = uintptr_t;
- static constexpr const unsigned bitsPerByte = 8;
- static constexpr const unsigned digitBits = sizeof(Digit) * bitsPerByte;
- static constexpr const unsigned halfDigitBits = digitBits / 2;
+ static constexpr const int bitsPerByte = 8;
+ static constexpr const int digitBits = sizeof(Digit) * bitsPerByte;
+ static constexpr const int halfDigitBits = digitBits / 2;
static constexpr const Digit halfDigitMask = (1ull << halfDigitBits) - 1;
static constexpr const int maxInt = 0x7FFFFFFF;
@@ -99,13 +98,12 @@
// maxInt / digitBits. However, we use a lower limit for now, because
// raising it later is easier than lowering it.
// Support up to 1 million bits.
- static const unsigned maxLength = 1024 * 1024 / (sizeof(void*) * bitsPerByte);
+ static const int maxLength = 1024 * 1024 / (sizeof(void*) * bitsPerByte);
- static uint64_t calculateMaximumCharactersRequired(unsigned length, unsigned radix, Digit lastDigit, bool sign);
+ static uint64_t calculateMaximumCharactersRequired(int length, int radix, Digit lastDigit, bool sign);
static void absoluteDivSmall(ExecState&, JSBigInt* x, Digit divisor, JSBigInt** quotient, Digit& remainder);
- static void internalMultiplyAdd(JSBigInt* source, Digit factor, Digit summand, unsigned, JSBigInt* result);
- static void multiplyAccumulate(JSBigInt* multiplicand, Digit multiplier, JSBigInt* accumulator, unsigned accumulatorIndex);
+ static void internalMultiplyAdd(JSBigInt* source, Digit factor, Digit summand, int, JSBigInt* result);
// Digit arithmetic helpers.
static Digit digitAdd(Digit a, Digit b, Digit& carry);
@@ -114,17 +112,17 @@
static Digit digitDiv(Digit high, Digit low, Digit divisor, Digit& remainder);
static Digit digitPow(Digit base, Digit exponent);
- static String toStringGeneric(ExecState&, JSBigInt*, unsigned radix);
+ static String toStringGeneric(ExecState&, JSBigInt*, int radix);
bool isZero();
template <typename CharType>
- static JSBigInt* parseInt(ExecState*, CharType* data, unsigned length);
+ static JSBigInt* parseInt(ExecState*, CharType* data, int length);
template <typename CharType>
- static JSBigInt* parseInt(ExecState*, VM&, CharType* data, unsigned length, unsigned startIndex, unsigned radix, bool allowEmptyString = true);
+ static JSBigInt* parseInt(ExecState*, VM&, CharType* data, int length, int startIndex, int radix, bool allowEmptyString = true);
- static JSBigInt* allocateFor(ExecState*, VM&, unsigned radix, unsigned charcount);
+ static JSBigInt* allocateFor(ExecState*, VM&, int radix, int charcount);
JSBigInt* rightTrim(VM&);
@@ -133,10 +131,10 @@
static size_t offsetOfData();
Digit* dataStorage();
- Digit digit(unsigned);
- void setDigit(unsigned, Digit);
+ Digit digit(int);
+ void setDigit(int, Digit);
- unsigned m_length;
+ int m_length;
bool m_sign;
};
diff --git a/Source/JavaScriptCore/runtime/Operations.h b/Source/JavaScriptCore/runtime/Operations.h
index 0fb21b48..1349aec 100644
--- a/Source/JavaScriptCore/runtime/Operations.h
+++ b/Source/JavaScriptCore/runtime/Operations.h
@@ -23,7 +23,6 @@
#include "CallFrame.h"
#include "ExceptionHelpers.h"
-#include "JSBigInt.h"
#include "JSCJSValue.h"
namespace JSC {
@@ -257,30 +256,6 @@
return jsAddSlowCase(callFrame, v1, v2);
}
-ALWAYS_INLINE JSValue jsMul(ExecState* state, JSValue v1, JSValue v2)
-{
- VM& vm = state->vm();
- auto scope = DECLARE_THROW_SCOPE(vm);
-
- JSValue leftNumber = v1.toPrimitive(state, PreferNumber);
- RETURN_IF_EXCEPTION(scope, { });
- JSValue rightNumber = v2.toPrimitive(state, PreferNumber);
- RETURN_IF_EXCEPTION(scope, { });
-
- if (leftNumber.isBigInt() || rightNumber.isBigInt()) {
- if (leftNumber.isBigInt() && rightNumber.isBigInt())
- return JSBigInt::multiply(state, asBigInt(leftNumber), asBigInt(rightNumber));
-
- throwTypeError(state, scope, ASCIILiteral("Invalid mix of BigInt and other type in multiplication."));
- return { };
- }
-
- scope.release();
- double leftValue = leftNumber.toNumber(state);
- double rightValue = rightNumber.toNumber(state);
- return jsNumber(leftValue * rightValue);
-}
-
inline bool scribbleFreeCells()
{
return !ASSERT_DISABLED || Options::scribbleFreeCells();