Issue #1240 - Part 5b - BigInt support for basic arithmetic operations. https://bugzilla.mozilla.org/show_bug.cgi?id=1471134 Parts 3-5.

This commit is contained in:
Brian Smith 2023-07-19 02:19:32 -05:00 committed by roytam1
commit 44b5d8dec3
8 changed files with 88 additions and 54 deletions

View file

@ -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);

View file

@ -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");
}

View file

@ -684,28 +684,22 @@ js::ecmaPow(double x, double y)
return pow(x, y);
}
bool
js::math_pow_handle(JSContext* cx, HandleValue base, HandleValue power, MutableHandleValue result)
{
double x;
if (!ToNumber(cx, base, &x))
return false;
double y;
if (!ToNumber(cx, power, &y))
return false;
double z = ecmaPow(x, y);
result.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());
double x;
if (!ToNumber(cx, args.get(0), &x))
return false;
double y;
if (!ToNumber(cx, args.get(1), &y))
return false;
double z = ecmaPow(x, y);
args.rval().setNumber(z);
return true;
}
uint64_t

View file

@ -123,10 +123,6 @@ math_min(JSContext* cx, unsigned argc, js::Value* vp);
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);

View file

@ -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) {

View file

@ -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;
}

View file

@ -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;
}
return true;
}
static MOZ_ALWAYS_INLINE bool
SubOperation(JSContext* cx, HandleValue lhs, HandleValue 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::add(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)
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
DivOperation(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(NumberDiv(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
ModOperation(JSContext* cx, HandleValue lhs, HandleValue rhs, MutableHandleValue res)
DivOperation(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
{
if (!ToNumeric(cx, lhs) || !ToNumeric(cx, rhs))
return false;
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, 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)
@ -4587,6 +4615,12 @@ js::ModValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, Mut
return ModOperation(cx, lhs, rhs, res);
}
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)
{

View file

@ -456,6 +456,9 @@ DivValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, Mutable
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);