mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-30 00:31:14 +00:00
LibJS: Rewrite Math.{max, min} to handle exceptions and NaNs properly
The specification requires that we immediately return a NaN during the iteration over the arguments if one is encountered. It also requires all arguments to be coerced into numbers before the operation starts, or else a number conversion exception could be missed due to the NaN early return.
This commit is contained in:
parent
24ffe91b16
commit
7507999230
Notes:
sideshowbarker
2024-07-18 16:50:50 +09:00
Author: https://github.com/IdanHo Commit: https://github.com/SerenityOS/serenity/commit/7507999230a Pull-request: https://github.com/SerenityOS/serenity/pull/7797 Reviewed-by: https://github.com/awesomekling Reviewed-by: https://github.com/linusg
|
@ -153,38 +153,42 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::round)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::max)
|
||||
{
|
||||
if (!vm.argument_count())
|
||||
return js_negative_infinity();
|
||||
|
||||
auto max = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
for (size_t i = 1; i < vm.argument_count(); ++i) {
|
||||
auto cur = vm.argument(i).to_number(global_object);
|
||||
Vector<Value> coerced;
|
||||
for (size_t i = 0; i < vm.argument_count(); ++i) {
|
||||
auto number = vm.argument(i).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if ((max.is_negative_zero() && cur.is_positive_zero()) || cur.as_double() > max.as_double())
|
||||
max = cur;
|
||||
coerced.append(number);
|
||||
}
|
||||
return max;
|
||||
|
||||
auto highest = js_negative_infinity();
|
||||
for (auto& number : coerced) {
|
||||
if (number.is_nan())
|
||||
return js_nan();
|
||||
if ((number.is_positive_zero() && highest.is_negative_zero()) || number.as_double() > highest.as_double())
|
||||
highest = number;
|
||||
}
|
||||
return highest;
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::min)
|
||||
{
|
||||
if (!vm.argument_count())
|
||||
return js_infinity();
|
||||
|
||||
auto min = vm.argument(0).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
for (size_t i = 1; i < vm.argument_count(); ++i) {
|
||||
auto cur = vm.argument(i).to_number(global_object);
|
||||
Vector<Value> coerced;
|
||||
for (size_t i = 0; i < vm.argument_count(); ++i) {
|
||||
auto number = vm.argument(i).to_number(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if ((min.is_positive_zero() && cur.is_negative_zero()) || cur.as_double() < min.as_double())
|
||||
min = cur;
|
||||
coerced.append(number);
|
||||
}
|
||||
return min;
|
||||
|
||||
auto lowest = js_infinity();
|
||||
for (auto& number : coerced) {
|
||||
if (number.is_nan())
|
||||
return js_nan();
|
||||
if ((number.is_negative_zero() && lowest.is_positive_zero()) || number.as_double() < lowest.as_double())
|
||||
lowest = number;
|
||||
}
|
||||
return lowest;
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::trunc)
|
||||
|
|
Loading…
Reference in a new issue