解决bigint中asUintN和asIntNc第一个参数大于2**32的情况

Signed-off-by: hwx1163501 <hanjing35@huawei.com>
issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I8TIA3
This commit is contained in:
hwx1163501 2024-01-04 11:13:36 +08:00
parent 2dddd6a382
commit 65de0a2dee
5 changed files with 26 additions and 7 deletions

View File

@ -110,6 +110,7 @@ JSTaggedValue BuiltinsNumber::IsInteger(EcmaRuntimeCallInfo *argv)
double value = JSTaggedNumber(msg.GetTaggedValue()).GetNumber();
// 3. Let integer be ToInteger(number).
JSTaggedNumber number = JSTaggedValue::ToInteger(thread, msg);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
// 4. If integer is not equal to number, return false.
// 5. Otherwise, return true.
result = (value == number.GetNumber());
@ -147,6 +148,7 @@ JSTaggedValue BuiltinsNumber::IsSafeInteger(EcmaRuntimeCallInfo *argv)
double value = JSTaggedNumber(msg.GetTaggedValue()).GetNumber();
// 3. Let integer be ToInteger(number).
JSTaggedNumber number = JSTaggedValue::ToInteger(thread, msg);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
// 4. If integer is not equal to number, return false.
// 5. If abs(integer) ≤ 2531, return true.
result = (value == number.GetNumber()) && std::abs(value) <= base::MAX_SAFE_INTEGER;
@ -284,6 +286,7 @@ JSTaggedValue BuiltinsNumber::ToFixed(EcmaRuntimeCallInfo *argv)
// 3. Let f be ToInteger(fractionDigits). (If fractionDigits is undefined, this step produces the value 0).
JSHandle<JSTaggedValue> digitArgv = GetCallArg(argv, 0);
JSTaggedNumber digitInt = JSTaggedValue::ToInteger(thread, digitArgv);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
if (digitArgv->IsUndefined()) {
digitInt = JSTaggedNumber(0);
}

View File

@ -1480,15 +1480,20 @@ JSHandle<BigInt> BigInt::FloorMod(JSThread *thread, JSHandle<BigInt> leftVal, JS
JSTaggedValue BigInt::AsUintN(JSThread *thread, JSTaggedNumber &bits, JSHandle<BigInt> bigint)
{
uint32_t bit = bits.ToUint32();
JSTaggedNumber number = JSTaggedValue::ToNumber(thread, bits);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
int64_t bit = base::NumberHelper::DoubleToInt64(number.GetNumber());
if (bit == 0) {
return Int32ToBigInt(thread, 0).GetTaggedValue();
}
if (bigint->IsZero()) {
return bigint.GetTaggedValue();
}
JSHandle<BigInt> exponent = Uint32ToBigInt(thread, bit);
JSHandle<BigInt> base = Int32ToBigInt(thread, 2); // 2 : base value
JSHandle<BigInt> exponent = Uint64ToBigInt(thread, bit);
JSHandle<BigInt> base = Int64ToBigInt(thread, 2); // 2 : base value
if (bit >= kMaxLengthBits && !bigint->GetSign()) {
return bigint.GetTaggedValue();
}
JSHandle<BigInt> tValue = Exponentiate(thread, base, exponent);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
return FloorMod(thread, bigint, tValue).GetTaggedValue();
@ -1496,16 +1501,21 @@ JSTaggedValue BigInt::AsUintN(JSThread *thread, JSTaggedNumber &bits, JSHandle<B
JSTaggedValue BigInt::AsintN(JSThread *thread, JSTaggedNumber &bits, JSHandle<BigInt> bigint)
{
uint32_t bit = bits.ToUint32();
JSTaggedNumber number = JSTaggedValue::ToNumber(thread, bits);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
int64_t bit = base::NumberHelper::DoubleToInt64(number.GetNumber());
if (bit == 0) {
return Int32ToBigInt(thread, 0).GetTaggedValue();
}
if (bigint->IsZero()) {
return bigint.GetTaggedValue();
}
JSHandle<BigInt> exp = Int32ToBigInt(thread, bit);
JSHandle<BigInt> exponent = Int32ToBigInt(thread, bit - 1);
JSHandle<BigInt> base = Int32ToBigInt(thread, 2); // 2 : base value
JSHandle<BigInt> exp = Int64ToBigInt(thread, bit);
JSHandle<BigInt> exponent = Int64ToBigInt(thread, bit - 1);
JSHandle<BigInt> base = Int64ToBigInt(thread, 2); // 2 : base value
if (bit >= kMaxLengthBits && !bigint->GetSign()) {
return bigint.GetTaggedValue();
}
JSHandle<BigInt> tValue = Exponentiate(thread, base, exp);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSHandle<BigInt> modValue = FloorMod(thread, bigint, tValue);

View File

@ -32,6 +32,7 @@ class BigInt : public TaggedObject {
public:
static constexpr uint32_t DATEBITS = sizeof(uint32_t) * 8; // 8 : one-bit number of bytes
static constexpr uint32_t MAXBITS = 1_MB; // 1 MB : Maximum space that can be opened up
static constexpr uint32_t kMaxLengthBits = 1 << 30; // ~1 billion.
static constexpr uint32_t MAXSIZE = MAXBITS / DATEBITS; // the maximum value of size
static constexpr uint32_t MAXOCTALVALUE = 7; // 7 : max octal value
static constexpr uint32_t BINARY = 2; // 2 : binary

View File

@ -100,3 +100,6 @@ try {
} catch (error) {
print(error);
}
print(BigInt.asUintN(2**32, 42n));
print(BigInt.asIntN(2**32, 42n));

View File

@ -24,3 +24,5 @@ SyntaxError
map val:4 key :9007199254740991
hmap val:4 key :9007199254740991
RangeError: invalid locale
42
42