Make Math.min() and Math.max() ECMA262 conform (#3465)

Math.min() and Math.max() functions should apply ToNumber on each arguments
always, even if a NaN argument occured previously and the result will be NaN.

ECMA262 v5.1 15.8.2:
"Each of the following Math object functions applies the ToNumber abstract
operator to each of its arguments (in left-to-right order if there is more
than one) and then performs a computation on the resulting Number value(s).

JerryScript-DCO-1.0-Signed-off-by: Csaba Osztrogonác oszi@inf.u-szeged.hu
This commit is contained in:
Csaba Osztrogonác 2019-12-20 08:57:17 +01:00 committed by Robert Fancsik
parent ea5ad2a06f
commit 85bb2113fe
2 changed files with 44 additions and 5 deletions

View File

@ -103,6 +103,7 @@ ecma_builtin_math_object_max_min (bool is_max, /**< 'max' or 'min' operation */
ecma_length_t args_number) /**< number of arguments */
{
ecma_number_t result_num = ecma_number_make_infinity (is_max);
bool nan_found = false;
while (args_number > 0)
{
@ -126,10 +127,13 @@ ecma_builtin_math_object_max_min (bool is_max, /**< 'max' or 'min' operation */
ecma_fast_free_value (value);
}
if (JERRY_UNLIKELY (ecma_number_is_nan (arg_num)))
arg++;
args_number--;
if (JERRY_UNLIKELY (nan_found || ecma_number_is_nan (arg_num)))
{
result_num = arg_num;
break;
nan_found = true;
continue;
}
if (ecma_number_is_zero (arg_num)
@ -149,9 +153,11 @@ ecma_builtin_math_object_max_min (bool is_max, /**< 'max' or 'min' operation */
result_num = arg_num;
}
}
}
arg++;
args_number--;
if (JERRY_UNLIKELY (nan_found))
{
result_num = ecma_number_make_nan ();
}
return ecma_make_number_value (result_num);

View File

@ -0,0 +1,33 @@
// Copyright JS Foundation and other contributors, http://js.foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
var str = "";
var a = {valueOf: function() { str += "a"; return 1;}};
var b = {valueOf: function() { str += "b"; return NaN;}};
var c = {valueOf: function() { str += "c"; return 2;}};
Math.min (a, b, c);
assert (str === "abc");
str = "";
Math.max (a, b, c);
assert (str === "abc");
str = "";
Math.pow(b,a);
assert (str === "ba");
str = "";
Math.atan2(b,a);
assert (str === "ba");