Skip to content

Commit

Permalink
fix(minifier): do not fold object comparisons (#8375)
Browse files Browse the repository at this point in the history
  • Loading branch information
Boshen committed Jan 9, 2025
1 parent a1752a0 commit 5516f7f
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 36 deletions.
65 changes: 29 additions & 36 deletions crates/oxc_ecmascript/src/constant_evaluation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,20 +266,18 @@ pub trait ConstantEvaluation<'a> {
_ => unreachable!(),
}))
}
BinaryOperator::LessThan => {
self.is_less_than(left, right, true).map(|value| match value {
ConstantValue::Undefined => ConstantValue::Boolean(false),
_ => value,
})
}
BinaryOperator::LessThan => self.is_less_than(left, right).map(|value| match value {
ConstantValue::Undefined => ConstantValue::Boolean(false),
_ => value,
}),
BinaryOperator::GreaterThan => {
self.is_less_than(right, left, false).map(|value| match value {
self.is_less_than(right, left).map(|value| match value {
ConstantValue::Undefined => ConstantValue::Boolean(false),
_ => value,
})
}
BinaryOperator::LessEqualThan => {
self.is_less_than(right, left, false).map(|value| match value {
self.is_less_than(right, left).map(|value| match value {
ConstantValue::Boolean(true) | ConstantValue::Undefined => {
ConstantValue::Boolean(false)
}
Expand All @@ -288,7 +286,7 @@ pub trait ConstantEvaluation<'a> {
})
}
BinaryOperator::GreaterEqualThan => {
self.is_less_than(left, right, true).map(|value| match value {
self.is_less_than(left, right).map(|value| match value {
ConstantValue::Boolean(true) | ConstantValue::Undefined => {
ConstantValue::Boolean(false)
}
Expand Down Expand Up @@ -444,42 +442,37 @@ pub trait ConstantEvaluation<'a> {
}

/// <https://tc39.es/ecma262/#sec-abstract-relational-comparison>
fn is_less_than(
&self,
left_expr: &Expression<'a>,
right_expr: &Expression<'a>,
_left_first: bool,
) -> Option<ConstantValue<'a>> {
let left = ValueType::from(left_expr);
let right = ValueType::from(right_expr);
fn is_less_than(&self, x: &Expression<'a>, y: &Expression<'a>) -> Option<ConstantValue<'a>> {
// a. Let px be ? ToPrimitive(x, number).
// b. Let py be ? ToPrimitive(y, number).
let px = ValueType::from(x);

if left.is_string() && right.is_string() {
let left_string = self.get_side_free_string_value(left_expr);
let right_string = self.get_side_free_string_value(right_expr);
if let (Some(left_string), Some(right_string)) = (left_string, right_string) {
// In JS, browsers parse \v differently. So do not compare strings if one contains \v.
if left_string.contains('\u{000B}') || right_string.contains('\u{000B}') {
return None;
}
return Some(ConstantValue::Boolean(
left_string.cmp(&right_string) == Ordering::Less,
));
}
// `.toString()` method is called and compared.
// TODO: bigint is handled very differently in the spec
if px.is_object() || px.is_undetermined() || px.is_bigint() {
return None;
}

// TODO: bigint is handled very differently in the spec
// See <https://tc39.es/ecma262/#sec-islessthan>
if left.is_bigint() || right.is_bigint() {
let py = ValueType::from(y);

if py.is_object() || py.is_undetermined() || py.is_bigint() {
return None;
}

let left_num = self.get_side_free_number_value(left_expr)?;
let right_num = self.get_side_free_number_value(right_expr)?;
if px.is_string() && py.is_string() {
let left_string = self.get_side_free_string_value(x)?;
let right_string = self.get_side_free_string_value(y)?;
return Some(ConstantValue::Boolean(left_string.cmp(&right_string) == Ordering::Less));
}

if left_num.is_nan() || right_num.is_nan() {
let left_num = self.get_side_free_number_value(x)?;
if left_num.is_nan() {
return Some(ConstantValue::Undefined);
}
let right_num = self.get_side_free_number_value(y)?;
if right_num.is_nan() {
return Some(ConstantValue::Undefined);
}

Some(ConstantValue::Boolean(left_num < right_num))
}
}
8 changes: 8 additions & 0 deletions crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,14 @@ mod test {
#[test]
fn test_comparison() {
test("(1, 2) !== 2", "false");
test_same("({} <= {})");
test_same("({} >= {})");
test_same("({} > {})");
test_same("({} < {})");
test_same("([] <= [])");
test_same("([] >= [])");
test_same("([] > [])");
test_same("([] < [])");
}

#[test]
Expand Down

0 comments on commit 5516f7f

Please sign in to comment.