Skip to content

Commit 571c04e

Browse files
committed
fix(ecmascript):handling for cases exceeding the i64 range
1 parent ed0b30b commit 571c04e

File tree

3 files changed

+31
-22
lines changed

3 files changed

+31
-22
lines changed

nova_vm/src/ecmascript/builtins/numbers_and_dates/bigint_objects/bigint_constructor.rs

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -204,26 +204,36 @@ impl BigIntConstructor {
204204
let bigint = to_big_int(agent, bigint.get(agent), gc.reborrow())
205205
.unbind()?
206206
.bind(gc.nogc());
207-
match bigint {
208-
BigInt::BigInt(int) => {
209-
let int = &agent[int].data;
210-
let modulus = 2i64.pow(bits);
211-
Ok(
212-
BigInt::from_num_bigint(agent, ((int % modulus) + modulus) % modulus)
213-
.into_value(),
214-
)
215-
}
216-
BigInt::SmallBigInt(int) => {
217-
let int = int.into_i64();
218-
if let Some(modulo) = 2i64
219-
.checked_pow(bits)
220-
.and_then(|base| int.checked_rem_euclid(base))
221-
{
207+
208+
match 2i64.checked_pow(bits) {
209+
Some(modulus) => match bigint {
210+
BigInt::BigInt(int) => {
211+
let int = &agent[int].data;
212+
Ok(
213+
BigInt::from_num_bigint(agent, ((int % modulus) + modulus) % modulus)
214+
.into_value(),
215+
)
216+
}
217+
BigInt::SmallBigInt(int) => {
218+
let int = int.into_i64();
219+
let modulo = int.rem_euclid(modulus);
222220
Ok(BigInt::from(SmallBigInt::try_from(modulo).unwrap()).into_value())
223-
} else {
224-
let modulus = num_bigint::BigInt::from(2).pow(bits);
225-
let result = ((int % modulus.clone()) + modulus.clone()) % modulus;
226-
Ok(BigInt::from_num_bigint(agent, result).into_value())
221+
}
222+
},
223+
None => {
224+
let modulus =
225+
num_bigint::BigInt::from_bytes_le(num_bigint::Sign::Plus, &[2]).pow(bits);
226+
match bigint {
227+
BigInt::BigInt(int) => {
228+
let int = &agent[int].data;
229+
let result = ((int % &modulus) + &modulus) % &modulus;
230+
Ok(BigInt::from_num_bigint(agent, result).into_value())
231+
}
232+
BigInt::SmallBigInt(int) => {
233+
let int = int.into_i64();
234+
let result = ((int % &modulus) + &modulus) % &modulus;
235+
Ok(BigInt::from_num_bigint(agent, result).into_value())
236+
}
227237
}
228238
}
229239
}

tests/expectations.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,6 @@
269269
"built-ins/Atomics/waitAsync/true-for-timeout.js": "FAIL",
270270
"built-ins/Atomics/waitAsync/waiterlist-block-indexedposition-wake.js": "FAIL",
271271
"built-ins/Atomics/waitAsync/was-woken-before-timeout.js": "FAIL",
272-
"built-ins/BigInt/asUintN/arithmetic.js": "CRASH",
273272
"built-ins/Boolean/proto-from-ctor-realm.js": "FAIL",
274273
"built-ins/DataView/proto-from-ctor-realm-sab.js": "FAIL",
275274
"built-ins/DataView/proto-from-ctor-realm.js": "FAIL",

tests/metrics.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"results": {
3-
"crash": 73,
3+
"crash": 72,
44
"fail": 7662,
5-
"pass": 39618,
5+
"pass": 39619,
66
"skip": 3325,
77
"timeout": 18,
88
"unresolved": 37

0 commit comments

Comments
 (0)