Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions crates/swc_ecma_minifier/src/compress/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,30 @@ pub(crate) fn eval_as_number(expr_ctx: ExprCtx, e: &Expr) -> Option<f64> {
return Some(base.pow(exponent).into());
}

"ceil" => {
let v = eval_as_number(expr_ctx, &args.first()?.expr)?;

return Some(v.ceil());
}

"floor" => {
let v = eval_as_number(expr_ctx, &args.first()?.expr)?;

return Some(v.floor());
}

"round" => {
let v = eval_as_number(expr_ctx, &args.first()?.expr)?;

return Some(v.round());
}

"sqrt" => {
let v = eval_as_number(expr_ctx, &args.first()?.expr)?;

return Some(v.sqrt());
}
Comment on lines 521 to 555
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new Math function implementations do not validate the number of arguments. Unlike the 'pow' function above (lines 510-519) which explicitly checks args.len() != 2, these functions should verify that exactly one argument is provided. While args.first()? handles the zero-argument case, multiple arguments should be rejected to match JavaScript's Math method behavior of ignoring extra arguments. Consider adding argument count validation for consistency and clarity.

Copilot uses AI. Check for mistakes.

_ => {}
},
_ => {}
Expand Down
44 changes: 44 additions & 0 deletions crates/swc_ecma_minifier/tests/fixture/issues/11078/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Basic constant folding for Math.ceil()
var a = Math.ceil(3.2);
var b = Math.ceil(-3.2);
var c = Math.ceil(0);
var d = Math.ceil(5);

// Basic constant folding for Math.floor()
var e = Math.floor(3.8);
var f = Math.floor(-3.2);
var g = Math.floor(0);
var h = Math.floor(5);

// Basic constant folding for Math.round()
var i = Math.round(3.5);
var j = Math.round(-3.5);
var k = Math.round(3.4);
var l = Math.round(-3.6);
var m = Math.round(0);

// Basic constant folding for Math.sqrt()
var n = Math.sqrt(16);
var o = Math.sqrt(0);
var p = Math.sqrt(2);
var q = Math.sqrt(9);

// Non-constant expressions should not be optimized
var x = 5;
var notOptimized1 = Math.ceil(x);
var notOptimized2 = Math.floor(x + 1);
var notOptimized3 = Math.round(x * 2);
var notOptimized4 = Math.sqrt(x);

// Chained optimization example
var result = Math.ceil(3.2);
if (result === 4) {
console.log("Optimized correctly");
}

// Nested Math calls should be optimized
var nested = Math.ceil(Math.sqrt(16));

// Math operations with constants
var expr1 = Math.ceil(1.5) + Math.floor(2.9);
var expr2 = Math.round(3.7) - Math.sqrt(4);
27 changes: 27 additions & 0 deletions crates/swc_ecma_minifier/tests/fixture/issues/11078/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
var a = 4;
var b = -3;
var c = 0;
var d = 5;
var e = 3;
var f = -4;
var g = 0;
var h = 5;
var i = 4;
var j = -3;
var k = 3;
var l = -4;
var m = 0;
var n = 4;
var o = 0;
var p = 1.4142135623730951;
var q = 3;
var x = 5;
var notOptimized1 = Math.ceil(x);
var notOptimized2 = Math.floor(x + 1);
var notOptimized3 = Math.round(2 * x);
var notOptimized4 = Math.sqrt(x);
var result = 4;
result === 4 && console.log("Optimized correctly");
var nested = 4;
var expr1 = 4;
var expr2 = 2;
Loading