mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-22 23:27:30 +09:00
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:
parent
25ee810247
commit
44b5d8dec3
8 changed files with 88 additions and 54 deletions
|
|
@ -778,7 +778,7 @@ RPow::recover(JSContext* cx, SnapshotIterator& iter) const
|
||||||
RootedValue result(cx);
|
RootedValue result(cx);
|
||||||
|
|
||||||
MOZ_ASSERT(base.isNumber() && power.isNumber());
|
MOZ_ASSERT(base.isNumber() && power.isNumber());
|
||||||
if (!js::math_pow_handle(cx, base, power, &result))
|
if (!js::PowValues(cx, &base, &power, &result))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
iter.storeInstructionResult(result);
|
iter.storeInstructionResult(result);
|
||||||
|
|
@ -805,7 +805,7 @@ RPowHalf::recover(JSContext* cx, SnapshotIterator& iter) const
|
||||||
power.setNumber(0.5);
|
power.setNumber(0.5);
|
||||||
|
|
||||||
MOZ_ASSERT(base.isNumber());
|
MOZ_ASSERT(base.isNumber());
|
||||||
if (!js::math_pow_handle(cx, base, power, &result))
|
if (!js::PowValues(cx, &base, &power, &result))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
iter.storeInstructionResult(result);
|
iter.storeInstructionResult(result);
|
||||||
|
|
|
||||||
|
|
@ -942,7 +942,7 @@ DoBinaryArithFallback(JSContext* cx, void* payload, ICBinaryArith_Fallback* stub
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
case JSOP_POW:
|
case JSOP_POW:
|
||||||
if (!math_pow_handle(cx, lhsCopy, rhsCopy, ret))
|
if (!PowValues(cx, &lhsCopy, &rhsCopy, ret))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
case JSOP_BITOR: {
|
case JSOP_BITOR: {
|
||||||
|
|
@ -1481,10 +1481,13 @@ DoUnaryArithFallback(JSContext* cx, void* payload, ICUnaryArith_Fallback* stub_,
|
||||||
res.setInt32(result);
|
res.setInt32(result);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case JSOP_NEG:
|
case JSOP_NEG: {
|
||||||
if (!NegOperation(cx, script, pc, val, res))
|
// We copy val here because the original value is needed below.
|
||||||
|
RootedValue valCopy(cx, val);
|
||||||
|
if (!NegOperation(cx, script, pc, &valCopy, res))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
MOZ_CRASH("Unexpected op");
|
MOZ_CRASH("Unexpected op");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -684,28 +684,22 @@ js::ecmaPow(double x, double y)
|
||||||
return pow(x, 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
|
bool
|
||||||
js::math_pow(JSContext* cx, unsigned argc, Value* vp)
|
js::math_pow(JSContext* cx, unsigned argc, Value* vp)
|
||||||
{
|
{
|
||||||
CallArgs args = CallArgsFromVp(argc, 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
|
uint64_t
|
||||||
|
|
|
||||||
|
|
@ -123,10 +123,6 @@ math_min(JSContext* cx, unsigned argc, js::Value* vp);
|
||||||
extern bool
|
extern bool
|
||||||
math_sqrt(JSContext* cx, unsigned argc, js::Value* vp);
|
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
|
extern bool
|
||||||
math_pow(JSContext* cx, unsigned argc, js::Value* vp);
|
math_pow(JSContext* cx, unsigned argc, js::Value* vp);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -529,6 +529,7 @@ Number(JSContext* cx, unsigned argc, Value* vp)
|
||||||
return false;
|
return false;
|
||||||
if (args[0].isBigInt())
|
if (args[0].isBigInt())
|
||||||
args[0].setNumber(BigInt::numberValue(args[0].toBigInt()));
|
args[0].setNumber(BigInt::numberValue(args[0].toBigInt()));
|
||||||
|
MOZ_ASSERT(args[0].isNumber());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isConstructing) {
|
if (!isConstructing) {
|
||||||
|
|
|
||||||
|
|
@ -390,7 +390,7 @@ DefVarOperation(JSContext* cx, HandleObject varobj, HandlePropertyName dn, unsig
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOZ_ALWAYS_INLINE bool
|
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)
|
MutableHandleValue res)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
@ -401,13 +401,16 @@ NegOperation(JSContext* cx, HandleScript script, jsbytecode* pc, HandleValue val
|
||||||
int32_t i;
|
int32_t i;
|
||||||
if (val.isInt32() && (i = val.toInt32()) != 0 && i != INT32_MIN) {
|
if (val.isInt32() && (i = val.toInt32()) != 0 && i != INT32_MIN) {
|
||||||
res.setInt32(-i);
|
res.setInt32(-i);
|
||||||
} else {
|
return true;
|
||||||
double d;
|
|
||||||
if (!ToNumber(cx, val, &d))
|
|
||||||
return false;
|
|
||||||
res.setNumber(-d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ToNumeric(cx, val))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (val.isBigInt())
|
||||||
|
return BigInt::neg(cx, val, res);
|
||||||
|
|
||||||
|
res.setNumber(-val.toNumber());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1328,50 +1328,63 @@ AddOperation(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, Muta
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
res.setString(str);
|
res.setString(str);
|
||||||
} else {
|
return true;
|
||||||
double l, r;
|
|
||||||
if (!ToNumber(cx, lhs, &l) || !ToNumber(cx, rhs, &r))
|
|
||||||
return false;
|
|
||||||
res.setNumber(l + r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOZ_ALWAYS_INLINE bool
|
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 (!ToNumeric(cx, lhs) || !ToNumeric(cx, rhs))
|
||||||
if (!ToNumber(cx, lhs, &d1) || !ToNumber(cx, rhs, &d2))
|
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOZ_ALWAYS_INLINE bool
|
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 (!ToNumeric(cx, lhs) || !ToNumeric(cx, rhs))
|
||||||
if (!ToNumber(cx, lhs, &d1) || !ToNumber(cx, rhs, &d2))
|
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOZ_ALWAYS_INLINE bool
|
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 (!ToNumeric(cx, lhs) || !ToNumeric(cx, rhs))
|
||||||
if (!ToNumber(cx, lhs, &d1) || !ToNumber(cx, rhs, &d2))
|
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOZ_ALWAYS_INLINE bool
|
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;
|
int32_t l, r;
|
||||||
|
|
||||||
if (lhs.isInt32() && rhs.isInt32() &&
|
if (lhs.isInt32() && rhs.isInt32() &&
|
||||||
(l = lhs.toInt32()) >= 0 && (r = rhs.toInt32()) > 0) {
|
(l = lhs.toInt32()) >= 0 && (r = rhs.toInt32()) > 0) {
|
||||||
int32_t mod = l % r;
|
int32_t mod = l % r;
|
||||||
|
|
@ -1379,11 +1392,26 @@ ModOperation(JSContext* cx, HandleValue lhs, HandleValue rhs, MutableHandleValue
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
double d1, d2;
|
if (!ToNumeric(cx, lhs) || !ToNumeric(cx, rhs))
|
||||||
if (!ToNumber(cx, lhs, &d1) || !ToNumber(cx, rhs, &d2))
|
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2327,7 +2355,7 @@ CASE(JSOP_SUB)
|
||||||
ReservedRooted<Value> lval(&rootValue0, REGS.sp[-2]);
|
ReservedRooted<Value> lval(&rootValue0, REGS.sp[-2]);
|
||||||
ReservedRooted<Value> rval(&rootValue1, REGS.sp[-1]);
|
ReservedRooted<Value> rval(&rootValue1, REGS.sp[-1]);
|
||||||
MutableHandleValue res = REGS.stackHandleAt(-2);
|
MutableHandleValue res = REGS.stackHandleAt(-2);
|
||||||
if (!SubOperation(cx, lval, rval, res))
|
if (!SubOperation(cx, &lval, &rval, res))
|
||||||
goto error;
|
goto error;
|
||||||
REGS.sp--;
|
REGS.sp--;
|
||||||
}
|
}
|
||||||
|
|
@ -2338,7 +2366,7 @@ CASE(JSOP_MUL)
|
||||||
ReservedRooted<Value> lval(&rootValue0, REGS.sp[-2]);
|
ReservedRooted<Value> lval(&rootValue0, REGS.sp[-2]);
|
||||||
ReservedRooted<Value> rval(&rootValue1, REGS.sp[-1]);
|
ReservedRooted<Value> rval(&rootValue1, REGS.sp[-1]);
|
||||||
MutableHandleValue res = REGS.stackHandleAt(-2);
|
MutableHandleValue res = REGS.stackHandleAt(-2);
|
||||||
if (!MulOperation(cx, lval, rval, res))
|
if (!MulOperation(cx, &lval, &rval, res))
|
||||||
goto error;
|
goto error;
|
||||||
REGS.sp--;
|
REGS.sp--;
|
||||||
}
|
}
|
||||||
|
|
@ -2349,7 +2377,7 @@ CASE(JSOP_DIV)
|
||||||
ReservedRooted<Value> lval(&rootValue0, REGS.sp[-2]);
|
ReservedRooted<Value> lval(&rootValue0, REGS.sp[-2]);
|
||||||
ReservedRooted<Value> rval(&rootValue1, REGS.sp[-1]);
|
ReservedRooted<Value> rval(&rootValue1, REGS.sp[-1]);
|
||||||
MutableHandleValue res = REGS.stackHandleAt(-2);
|
MutableHandleValue res = REGS.stackHandleAt(-2);
|
||||||
if (!DivOperation(cx, lval, rval, res))
|
if (!DivOperation(cx, &lval, &rval, res))
|
||||||
goto error;
|
goto error;
|
||||||
REGS.sp--;
|
REGS.sp--;
|
||||||
}
|
}
|
||||||
|
|
@ -2360,7 +2388,7 @@ CASE(JSOP_MOD)
|
||||||
ReservedRooted<Value> lval(&rootValue0, REGS.sp[-2]);
|
ReservedRooted<Value> lval(&rootValue0, REGS.sp[-2]);
|
||||||
ReservedRooted<Value> rval(&rootValue1, REGS.sp[-1]);
|
ReservedRooted<Value> rval(&rootValue1, REGS.sp[-1]);
|
||||||
MutableHandleValue res = REGS.stackHandleAt(-2);
|
MutableHandleValue res = REGS.stackHandleAt(-2);
|
||||||
if (!ModOperation(cx, lval, rval, res))
|
if (!ModOperation(cx, &lval, &rval, res))
|
||||||
goto error;
|
goto error;
|
||||||
REGS.sp--;
|
REGS.sp--;
|
||||||
}
|
}
|
||||||
|
|
@ -2371,7 +2399,7 @@ CASE(JSOP_POW)
|
||||||
ReservedRooted<Value> lval(&rootValue0, REGS.sp[-2]);
|
ReservedRooted<Value> lval(&rootValue0, REGS.sp[-2]);
|
||||||
ReservedRooted<Value> rval(&rootValue1, REGS.sp[-1]);
|
ReservedRooted<Value> rval(&rootValue1, REGS.sp[-1]);
|
||||||
MutableHandleValue res = REGS.stackHandleAt(-2);
|
MutableHandleValue res = REGS.stackHandleAt(-2);
|
||||||
if (!math_pow_handle(cx, lval, rval, res))
|
if (!PowOperation(cx, &lval, &rval, res))
|
||||||
goto error;
|
goto error;
|
||||||
REGS.sp--;
|
REGS.sp--;
|
||||||
}
|
}
|
||||||
|
|
@ -2399,7 +2427,7 @@ CASE(JSOP_NEG)
|
||||||
{
|
{
|
||||||
ReservedRooted<Value> val(&rootValue0, REGS.sp[-1]);
|
ReservedRooted<Value> val(&rootValue0, REGS.sp[-1]);
|
||||||
MutableHandleValue res = REGS.stackHandleAt(-1);
|
MutableHandleValue res = REGS.stackHandleAt(-1);
|
||||||
if (!NegOperation(cx, script, REGS.pc, val, res))
|
if (!NegOperation(cx, script, REGS.pc, &val, res))
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
END_CASE(JSOP_NEG)
|
END_CASE(JSOP_NEG)
|
||||||
|
|
@ -4587,6 +4615,12 @@ js::ModValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, Mut
|
||||||
return ModOperation(cx, lhs, rhs, res);
|
return ModOperation(cx, lhs, rhs, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
js::PowValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
|
||||||
|
{
|
||||||
|
return PowOperation(cx, lhs, rhs, res);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
js::UrshValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
|
js::UrshValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -456,6 +456,9 @@ DivValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, Mutable
|
||||||
bool
|
bool
|
||||||
ModValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res);
|
ModValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res);
|
||||||
|
|
||||||
|
bool
|
||||||
|
PowValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
UrshValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res);
|
UrshValues(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue