summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Smith <brian@dbsoft.org>2023-07-19 02:19:32 -0500
committerBrian Smith <brian@dbsoft.org>2023-07-19 02:19:32 -0500
commit37e02a4bd459f4c6def492230a9b50cf4c3fdf4a (patch)
tree6865089c24f67d378267d80fe9955158fe359ffc
parent93a10f9e2f4e3480a9b89eb820c92b6c5b68dc24 (diff)
downloaduxp-37e02a4bd459f4c6def492230a9b50cf4c3fdf4a.tar.gz
Issue #1240 - Part 5b - BigInt support for basic arithmetic operations.
https://bugzilla.mozilla.org/show_bug.cgi?id=1471134 Parts 3-5.
-rw-r--r--js/src/jit/Recover.cpp4
-rw-r--r--js/src/jit/SharedIC.cpp9
-rw-r--r--js/src/jsmath.cpp18
-rw-r--r--js/src/jsmath.h4
-rw-r--r--js/src/jsnum.cpp1
-rw-r--r--js/src/vm/Interpreter-inl.h15
-rw-r--r--js/src/vm/Interpreter.cpp88
-rw-r--r--js/src/vm/Interpreter.h3
8 files changed, 88 insertions, 54 deletions
diff --git a/js/src/jit/Recover.cpp b/js/src/jit/Recover.cpp
index 833ad871d0..b9bc5a0f35 100644
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -778,7 +778,7 @@ RPow::recover(JSContext* cx, SnapshotIterator& iter) const
RootedValue result(cx);
MOZ_ASSERT(base.isNumber() && power.isNumber());
- if (!js::math_pow_handle(cx, base, power, &result))
+ if (!js::PowValues(cx, &base, &power, &result))
return false;
iter.storeInstructionResult(result);
@@ -805,7 +805,7 @@ RPowHalf::recover(JSContext* cx, SnapshotIterator& iter) const
power.setNumber(0.5);
MOZ_ASSERT(base.isNumber());
- if (!js::math_pow_handle(cx, base, power, &result))
+ if (!js::PowValues(cx, &base, &power, &result))
return false;
iter.storeInstructionResult(result);
diff --git a/js/src/jit/SharedIC.cpp b/js/src/jit/SharedIC.cpp
index f8f4433af7..40e4563510 100644
--- a/js/src/jit/SharedIC.cpp
+++ b/js/src/jit/SharedIC.cpp
@@ -942,7 +942,7 @@ DoBinaryArithFallback(JSContext* cx, void* payload, ICBinaryArith_Fallback* stub
return false;
break;
case JSOP_POW:
- if (!math_pow_handle(cx, lhsCopy, rhsCopy, ret))
+ if (!PowValues(cx, &lhsCopy, &rhsCopy, ret))
return false;
break;
case JSOP_BITOR: {
@@ -1481,10 +1481,13 @@ DoUnaryArithFallback(JSContext* cx, void* payload, ICUnaryArith_Fallback* stub_,
res.setInt32(result);
break;
}
- case JSOP_NEG:
- if (!NegOperation(cx, script, pc, val, res))
+ case JSOP_NEG: {
+ // We copy val here because the original value is needed below.
+ RootedValue valCopy(cx, val);
+ if (!NegOperation(cx, script, pc, &valCopy, res))
return false;
break;
+ }
default:
MOZ_CRASH("Unexpected op");
}
diff --git a/js/src/jsmath.cpp b/js/src/jsmath.cpp
index b98dba57cd..8f17ff15ca 100644
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -685,29 +685,23 @@ js::ecmaPow(double x, double y)
}
bool
-js::math_pow_handle(JSContext* cx, HandleValue base, HandleValue power, MutableHandleValue result)
+js::math_pow(JSContext* cx, unsigned argc, Value* vp)
{
+ CallArgs args = CallArgsFromVp(argc, vp);
+
double x;
- if (!ToNumber(cx, base, &x))
+ if (!ToNumber(cx, args.get(0), &x))
return false;
double y;
- if (!ToNumber(cx, power, &y))
+ if (!ToNumber(cx, args.get(1), &y))
return false;
double z = ecmaPow(x, y);
- result.setNumber(z);
+ args.rval().setNumber(z);
return true;
}
-bool
-js::math_pow(JSContext* cx, unsigned argc, Value* vp)
-{
- CallArgs args = CallArgsFromVp(argc, vp);
-
- return math_pow_handle(cx, args.get(0), args.get(1), args.rval());
-}
-
uint64_t
js::GenerateRandomSeed()
{
diff --git a/js/src/jsmath.h b/js/src/jsmath.h
index e716edce14..558d3d356a 100644
--- a/js/src/jsmath.h
+++ b/js/src/jsmath.h
@@ -124,10 +124,6 @@ extern bool
math_sqrt(JSContext* cx, unsigned argc, js::Value* vp);
extern bool
-math_pow_handle(JSContext* cx, js::HandleValue base, js::HandleValue power,
- js::MutableHandleValue result);
-
-extern bool
math_pow(JSContext* cx, unsigned argc, js::Value* vp);
extern bool
diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp
index 62f694c216..c64a1149f0 100644
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -529,6 +529,7 @@ Number(JSContext* cx, unsigned argc, Value* vp)
return false;
if (args[0].isBigInt())
args[0].setNumber(BigInt::numberValue(args[0].toBigInt()));
+ MOZ_ASSERT(args[0].isNumber());
}
if (!isConstructing) {
diff --git a/js/src/vm/Interpreter-inl.h b/js/src/vm/Interpreter-inl.h
index 79a4b90200..579cdc13ab 100644
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -390,7 +390,7 @@ DefVarOperation(JSContext* cx, HandleObject varobj, HandlePropertyName dn, unsig
}
static MOZ_ALWAYS_INLINE bool
-NegOperation(JSContext* cx, HandleScript script, jsbytecode* pc, HandleValue val,
+NegOperation(JSContext* cx, HandleScript script, jsbytecode* pc, MutableHandleValue val,
MutableHandleValue res)
{
/*
@@ -401,13 +401,16 @@ NegOperation(JSContext* cx, HandleScript script, jsbytecode* pc, HandleValue val
int32_t i;
if (val.isInt32() && (i = val.toInt32()) != 0 && i != INT32_MIN) {
res.setInt32(-i);
- } else {
- double d;
- if (!ToNumber(cx, val, &d))
- return false;
- res.setNumber(-d);
+ return true;
}
+ if (!ToNumeric(cx, val))
+ return false;
+
+ if (val.isBigInt())
+ return BigInt::neg(cx, val, res);
+
+ res.setNumber(-val.toNumber());
return true;
}
diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp
index b00f50971c..e8e7b6ef3b 100644
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -1328,50 +1328,63 @@ AddOperation(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, Muta
return false;
}
res.setString(str);
- } else {
- double l, r;
- if (!ToNumber(cx, lhs, &l) || !ToNumber(cx, rhs, &r))
- return false;
- res.setNumber(l + r);
+ return true;
}
+ if (!ToNumeric(cx, lhs) || !ToNumeric(cx, rhs))
+ return false;
+
+ if (lhs.isBigInt() || rhs.isBigInt())
+ return BigInt::add(cx, lhs, rhs, res);
+
+ res.setNumber(lhs.toNumber() + rhs.toNumber());
return true;
}
static MOZ_ALWAYS_INLINE bool
-SubOperation(JSContext* cx, HandleValue lhs, HandleValue rhs, MutableHandleValue res)
+SubOperation(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
{
- double d1, d2;
- if (!ToNumber(cx, lhs, &d1) || !ToNumber(cx, rhs, &d2))
+ if (!ToNumeric(cx, lhs) || !ToNumeric(cx, rhs))
return false;
- res.setNumber(d1 - d2);
+
+ if (lhs.isBigInt() || rhs.isBigInt())
+ return BigInt::sub(cx, lhs, rhs, res);
+
+ res.setNumber(lhs.toNumber() - rhs.toNumber());
return true;
}
static MOZ_ALWAYS_INLINE bool
-MulOperation(JSContext* cx, HandleValue lhs, HandleValue rhs, MutableHandleValue res)
+MulOperation(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
{
- double d1, d2;
- if (!ToNumber(cx, lhs, &d1) || !ToNumber(cx, rhs, &d2))
+ if (!ToNumeric(cx, lhs) || !ToNumeric(cx, rhs))
return false;
- res.setNumber(d1 * d2);
+
+ if (lhs.isBigInt() || rhs.isBigInt())
+ return BigInt::mul(cx, lhs, rhs, res);
+
+ res.setNumber(lhs.toNumber() * rhs.toNumber());
return true;
}
static MOZ_ALWAYS_INLINE bool
-DivOperation(JSContext* cx, HandleValue lhs, HandleValue rhs, MutableHandleValue res)
+DivOperation(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
{
- double d1, d2;
- if (!ToNumber(cx, lhs, &d1) || !ToNumber(cx, rhs, &d2))
+ if (!ToNumeric(cx, lhs) || !ToNumeric(cx, rhs))
return false;
- res.setNumber(NumberDiv(d1, d2));
+
+ if (lhs.isBigInt() || rhs.isBigInt())
+ return BigInt::div(cx, lhs, rhs, res);
+
+ res.setNumber(NumberDiv(lhs.toNumber(), rhs.toNumber()));
return true;
}
static MOZ_ALWAYS_INLINE bool
-ModOperation(JSContext* cx, HandleValue lhs, HandleValue rhs, MutableHandleValue res)
+ModOperation(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
{
int32_t l, r;
+
if (lhs.isInt32() && rhs.isInt32() &&
(l = lhs.toInt32()) >= 0 && (r = rhs.toInt32()) > 0) {
int32_t mod = l % r;
@@ -1379,11 +1392,26 @@ ModOperation(JSContext* cx, HandleValue lhs, HandleValue rhs, MutableHandleValue
return true;
}
- double d1, d2;
- if (!ToNumber(cx, lhs, &d1) || !ToNumber(cx, rhs, &d2))
+ if (!ToNumeric(cx, lhs) || !ToNumeric(cx, rhs))
return false;
- res.setNumber(NumberMod(d1, d2));
+ if (lhs.isBigInt() || rhs.isBigInt())
+ return BigInt::mod(cx, lhs, rhs, res);
+
+ res.setNumber(NumberMod(lhs.toNumber(), rhs.toNumber()));
+ return true;
+}
+
+static MOZ_ALWAYS_INLINE bool
+PowOperation(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
+{
+ if (!ToNumeric(cx, lhs) || !ToNumeric(cx, rhs))
+ return false;
+
+ if (lhs.isBigInt() || rhs.isBigInt())
+ return BigInt::pow(cx, lhs, rhs, res);
+
+ res.setNumber(ecmaPow(lhs.toNumber(), rhs.toNumber()));
return true;
}
@@ -2327,7 +2355,7 @@ CASE(JSOP_SUB)
ReservedRooted<Value> lval(&rootValue0, REGS.sp[-2]);
ReservedRooted<Value> rval(&rootValue1, REGS.sp[-1]);
MutableHandleValue res = REGS.stackHandleAt(-2);
- if (!SubOperation(cx, lval, rval, res))
+ if (!SubOperation(cx, &lval, &rval, res))
goto error;
REGS.sp--;
}
@@ -2338,7 +2366,7 @@ CASE(JSOP_MUL)
ReservedRooted<Value> lval(&rootValue0, REGS.sp[-2]);
ReservedRooted<Value> rval(&rootValue1, REGS.sp[-1]);
MutableHandleValue res = REGS.stackHandleAt(-2);
- if (!MulOperation(cx, lval, rval, res))
+ if (!MulOperation(cx, &lval, &rval, res))
goto error;
REGS.sp--;
}
@@ -2349,7 +2377,7 @@ CASE(JSOP_DIV)
ReservedRooted<Value> lval(&rootValue0, REGS.sp[-2]);
ReservedRooted<Value> rval(&rootValue1, REGS.sp[-1]);
MutableHandleValue res = REGS.stackHandleAt(-2);
- if (!DivOperation(cx, lval, rval, res))
+ if (!DivOperation(cx, &lval, &rval, res))
goto error;
REGS.sp--;
}
@@ -2360,7 +2388,7 @@ CASE(JSOP_MOD)
ReservedRooted<Value> lval(&rootValue0, REGS.sp[-2]);
ReservedRooted<Value> rval(&rootValue1, REGS.sp[-1]);
MutableHandleValue res = REGS.stackHandleAt(-2);
- if (!ModOperation(cx, lval, rval, res))
+ if (!ModOperation(cx, &lval, &rval, res))
goto error;
REGS.sp--;
}
@@ -2371,7 +2399,7 @@ CASE(JSOP_POW)
ReservedRooted<Value> lval(&rootValue0, REGS.sp[-2]);
ReservedRooted<Value> rval(&rootValue1, REGS.sp[-1]);
MutableHandleValue res = REGS.stackHandleAt(-2);
- if (!math_pow_handle(cx, lval, rval, res))
+ if (!PowOperation(cx, &lval, &rval, res))
goto error;
REGS.sp--;
}
@@ -2399,7 +2427,7 @@ CASE(JSOP_NEG)
{
ReservedRooted<Value> val(&rootValue0, REGS.sp[-1]);
MutableHandleValue res = REGS.stackHandleAt(-1);
- if (!NegOperation(cx, script, REGS.pc, val, res))
+ if (!NegOperation(cx, script, REGS.pc, &val, res))
goto error;
}
END_CASE(JSOP_NEG)
@@ -4588,6 +4616,12 @@ js::ModValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, Mut
}
bool
+js::PowValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
+{
+ return PowOperation(cx, lhs, rhs, res);
+}
+
+bool
js::UrshValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
{
return UrshOperation(cx, lhs, rhs, res);
diff --git a/js/src/vm/Interpreter.h b/js/src/vm/Interpreter.h
index 1927e8cc7f..3c7b80a14c 100644
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -457,6 +457,9 @@ bool
ModValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res);
bool
+PowValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res);
+
+bool
UrshValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res);
bool