mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 07:18:39 +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);
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue