diff --git a/boa/src/builtins/bigint/operations.rs b/boa/src/builtins/bigint/operations.rs index 7edbc898c1d..4963d048dc2 100644 --- a/boa/src/builtins/bigint/operations.rs +++ b/boa/src/builtins/bigint/operations.rs @@ -4,6 +4,7 @@ use num_traits::cast::ToPrimitive; use num_traits::pow::Pow; use super::BigInt; +use std::ops::{Neg, Not}; impl BigInt { #[inline] @@ -86,7 +87,7 @@ impl_bigint_operator!(BitAnd, bitand, BitAndAssign, bitand_assign); impl_bigint_operator!(BitOr, bitor, BitOrAssign, bitor_assign); impl_bigint_operator!(BitXor, bitxor, BitXorAssign, bitxor_assign); -impl std::ops::Neg for BigInt { +impl Neg for BigInt { type Output = Self; fn neg(self) -> Self::Output { @@ -94,6 +95,22 @@ impl std::ops::Neg for BigInt { } } +impl Not for BigInt { + type Output = Self; + + fn not(self) -> BigInt { + Self(!self.0) + } +} + +impl<'a> Not for &'a BigInt { + type Output = BigInt; + + fn not(self) -> BigInt { + BigInt(!self.clone().0) + } +} + impl std::fmt::Debug for BigInt { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.0) diff --git a/boa/src/syntax/ast/node/operator/unary_op/mod.rs b/boa/src/syntax/ast/node/operator/unary_op/mod.rs index 30e70d92112..4157d90cf5b 100644 --- a/boa/src/syntax/ast/node/operator/unary_op/mod.rs +++ b/boa/src/syntax/ast/node/operator/unary_op/mod.rs @@ -83,18 +83,14 @@ impl Executable for UnaryOp { op::UnaryOp::Not => self.target().run(context)?.not(context)?.into(), op::UnaryOp::Tilde => { let num_v_a = self.target().run(context)?.to_numeric_number(context)?; - if num_v_a.is_nan() { - Value::from(-1) - } else if num_v_a.is_infinite() { - Value::from(-1) + if num_v_a.is_nan() || num_v_a.is_infinite() { + Value::from(-1) // special case for inf or nan + } else if self.target.run(context)?.is_bigint() { + Value::from(!self.target.run(context)?.as_bigint().unwrap()) + // add bigint support } else { - if self.target.run(context)?.is_bigint() { - Value::from(Value::from(-num_v_a-1f64).to_bigint(context)?) - } - else { - let temp = (num_v_a as i64) & 0x00000000ffffffff; - Value::from(!(temp as i32)) - } + let masked = (num_v_a as i64) & 0x00000000ffffffff; // converts float to i32 following spec to ignore MSB using mask + Value::from(!(masked as i32)) // Nots i32 conversion and creates value from this } } op::UnaryOp::Void => {