Skip to content

Commit

Permalink
Use new JsNumber API
Browse files Browse the repository at this point in the history
  • Loading branch information
levi-nz committed Jul 16, 2024
1 parent 7e16e74 commit fe2a989
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 29 deletions.
29 changes: 4 additions & 25 deletions crates/swc_ecma_transforms_optimization/src/simplify/expr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ use swc_ecma_utils::{
StringType, SymbolType, UndefinedType, Value,
is_literal, number::JsNumber, prop_name_eq, to_int32, BoolType, ExprCtx, ExprExt, NullType,
NumberType, ObjectType, StringType, SymbolType, UndefinedType, Value,
is_literal,
number::{ToJsInt32, ToJsUint32},
prop_name_eq, to_int32, BoolType, ExprCtx, ExprExt, NullType, NumberType, ObjectType,
StringType, SymbolType, UndefinedType, Value,
};
use swc_ecma_visit::{as_folder, standard_only_visit_mut, VisitMut, VisitMutWith};
use Value::{Known, Unknown};
Expand Down Expand Up @@ -655,29 +651,12 @@ impl SimplifyExpr {
(Known(lv), Known(rv)) => (lv, rv),
_ => unreachable!(),
};
let (lv, rv) = (JsNumber::from(lv), JsNumber::from(rv));

Known(match op {
op!("<<") => {
// https://262.ecma-international.org/5.1/#sec-11.7.1
let lnum = lv.to_js_int32();
let rnum = rv.to_js_uint32();

(lnum << (rnum & 0x1f)) as f64
}
op!(">>") => {
// https://262.ecma-international.org/5.1/#sec-11.7.2
let lnum = lv.to_js_int32();
let rnum = rv.to_js_uint32();

(lnum >> (rnum & 0x1f)) as f64
}
op!(">>>") => {
// https://262.ecma-international.org/5.1/#sec-11.7.3
let lnum = lv.to_js_uint32();
let rnum = rv.to_js_uint32();

(lnum >> (rnum & 0x1f)) as f64
}
op!("<<") => *(lv << rv),
op!(">>") => *(lv >> rv),
op!(">>>") => *(lv.unsigned_shr(rv)),

_ => unreachable!("Unknown bit operator {:?}", op),
})
Expand Down
29 changes: 25 additions & 4 deletions crates/swc_ecma_utils/src/number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,20 +95,40 @@ impl std::ops::Deref for JsNumber {
impl JsNumber {
// https://tc39.es/ecma262/#sec-toint32
fn as_int32(&self) -> i32 {
if !self.0.is_finite() {
if !self.0.is_finite() || self.0 == 0.0 {
return 0;
}

self.0.trunc() as i32
const TWO_32: f64 = u32::MAX as f64 + 1.0; // 2^32
const TWO_31: f64 = i32::MAX as f64 + 1.0; // 2^31

let pos_int = self.signum() * self.abs().floor();
let int32_bit = pos_int % TWO_32;

(if int32_bit >= TWO_31 {
int32_bit - TWO_32
} else {
int32_bit
}) as i32
}

// https://tc39.es/ecma262/#sec-touint32
fn as_uint32(&self) -> u32 {
if !self.0.is_finite() {
if !self.0.is_finite() || self.0 == 0.0 {
return 0;
}

self.0.trunc() as u32
const TWO_32: f64 = u32::MAX as f64 + 1.0; // 2^32

let pos_int = self.signum() * self.abs().floor();
let result = pos_int % TWO_32;
// Extra step: since `x as u32` doesn't overflow, we have to add if result is
// negative
(if result < 0.0 {
result + TWO_32
} else {
result
}) as u32
}
}

Expand Down Expand Up @@ -349,6 +369,7 @@ mod test_js_number {
assert_eq!(JsNumber(-0.0).as_uint32(), 0);
assert_eq!(JsNumber(f64::INFINITY).as_uint32(), 0);
assert_eq!(JsNumber(f64::NEG_INFINITY).as_uint32(), 0);
assert_eq!(JsNumber(-8.0).as_uint32(), 4294967288);
}

#[test]
Expand Down

0 comments on commit fe2a989

Please sign in to comment.