mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:17:34 +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
1 changed files with 26 additions and 22 deletions
|
@ -153,38 +153,42 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::round)
|
||||||
|
|
||||||
JS_DEFINE_NATIVE_FUNCTION(MathObject::max)
|
JS_DEFINE_NATIVE_FUNCTION(MathObject::max)
|
||||||
{
|
{
|
||||||
if (!vm.argument_count())
|
Vector<Value> coerced;
|
||||||
return js_negative_infinity();
|
for (size_t i = 0; i < vm.argument_count(); ++i) {
|
||||||
|
auto number = vm.argument(i).to_number(global_object);
|
||||||
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);
|
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
if ((max.is_negative_zero() && cur.is_positive_zero()) || cur.as_double() > max.as_double())
|
coerced.append(number);
|
||||||
max = cur;
|
|
||||||
}
|
}
|
||||||
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)
|
JS_DEFINE_NATIVE_FUNCTION(MathObject::min)
|
||||||
{
|
{
|
||||||
if (!vm.argument_count())
|
Vector<Value> coerced;
|
||||||
return js_infinity();
|
for (size_t i = 0; i < vm.argument_count(); ++i) {
|
||||||
|
auto number = vm.argument(i).to_number(global_object);
|
||||||
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);
|
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
if ((min.is_positive_zero() && cur.is_negative_zero()) || cur.as_double() < min.as_double())
|
coerced.append(number);
|
||||||
min = cur;
|
|
||||||
}
|
}
|
||||||
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)
|
JS_DEFINE_NATIVE_FUNCTION(MathObject::trunc)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue