1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation
2425bb815Sopenharmony_ci *
3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License.
5425bb815Sopenharmony_ci * You may obtain a copy of the License at
6425bb815Sopenharmony_ci *
7425bb815Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8425bb815Sopenharmony_ci *
9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS
11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and
13425bb815Sopenharmony_ci * limitations under the License.
14425bb815Sopenharmony_ci */
15425bb815Sopenharmony_ci
16425bb815Sopenharmony_ci#include <math.h>
17425bb815Sopenharmony_ci
18425bb815Sopenharmony_ci#include "ecma-alloc.h"
19425bb815Sopenharmony_ci#include "ecma-builtins.h"
20425bb815Sopenharmony_ci#include "ecma-conversion.h"
21425bb815Sopenharmony_ci#include "ecma-exceptions.h"
22425bb815Sopenharmony_ci#include "ecma-gc.h"
23425bb815Sopenharmony_ci#include "ecma-globals.h"
24425bb815Sopenharmony_ci#include "ecma-helpers.h"
25425bb815Sopenharmony_ci#include "ecma-number-arithmetic.h"
26425bb815Sopenharmony_ci#include "ecma-objects.h"
27425bb815Sopenharmony_ci#include "ecma-objects-general.h"
28425bb815Sopenharmony_ci#include "ecma-try-catch-macro.h"
29425bb815Sopenharmony_ci#include "jrt.h"
30425bb815Sopenharmony_ci#include "jrt-libc-includes.h"
31425bb815Sopenharmony_ci
32425bb815Sopenharmony_ci#if defined (WIN32)
33425bb815Sopenharmony_ci#include <intrin.h>
34425bb815Sopenharmony_ci#endif
35425bb815Sopenharmony_ci
36425bb815Sopenharmony_ci#if ENABLED (JERRY_BUILTIN_MATH)
37425bb815Sopenharmony_ci
38425bb815Sopenharmony_ci#define ECMA_BUILTINS_INTERNAL
39425bb815Sopenharmony_ci#include "ecma-builtins-internal.h"
40425bb815Sopenharmony_ci
41425bb815Sopenharmony_ci/**
42425bb815Sopenharmony_ci * This object has a custom dispatch function.
43425bb815Sopenharmony_ci */
44425bb815Sopenharmony_ci#define BUILTIN_CUSTOM_DISPATCH
45425bb815Sopenharmony_ci
46425bb815Sopenharmony_ci/**
47425bb815Sopenharmony_ci * List of built-in routine identifiers.
48425bb815Sopenharmony_ci */
49425bb815Sopenharmony_cienum
50425bb815Sopenharmony_ci{
51425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_ROUTINE_START = ECMA_BUILTIN_ID__COUNT - 1,
52425bb815Sopenharmony_ci
53425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_ABS, /* ECMA-262 v5, 15.8.2.1 */
54425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_ACOS, /* ECMA-262 v5, 15.8.2.2 */
55425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_ASIN, /* ECMA-262 v5, 15.8.2.3 */
56425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_ATAN, /* ECMA-262 v5, 15.8.2.4 */
57425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_CEIL, /* ECMA-262 v5, 15.8.2.6 */
58425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_COS, /* ECMA-262 v5, 15.8.2.7 */
59425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_EXP, /* ECMA-262 v5, 15.8.2.8 */
60425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_FLOOR, /* ECMA-262 v5, 15.8.2.9 */
61425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_LOG, /* ECMA-262 v5, 15.8.2.10 */
62425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_ROUND, /* ECMA-262 v5, 15.8.2.15 */
63425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_SIN, /* ECMA-262 v5, 15.8.2.16 */
64425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_SQRT, /* ECMA-262 v5, 15.8.2.17 */
65425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_TAN, /* ECMA-262 v5, 15.8.2.18 */
66425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
67425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_ACOSH, /* ECMA-262 v6, 20.2.2.3  */
68425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_ASINH, /* ECMA-262 v6, 20.2.2.5  */
69425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_ATANH, /* ECMA-262 v6, 20.2.2.7  */
70425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_CBRT, /* ECMA-262 v6, 20.2.2.9  */
71425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_CLZ32, /* ECMA-262 v6, 20.2.2.11  */
72425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_COSH, /* ECMA-262 v6, 20.2.2.13  */
73425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_EXPM1, /* ECMA-262 v6, 20.2.2.15  */
74425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_FROUND, /* ECMA-262 v6, 20.2.2.17  */
75425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_LOG1P, /* ECMA-262 v6, 20.2.2.21  */
76425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_LOG10, /* ECMA-262 v6, 20.2.2.22  */
77425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_LOG2, /* ECMA-262 v6, 20.2.2.23  */
78425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_SIGN, /* ECMA-262 v6, 20.2.2.29 */
79425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_SINH, /* ECMA-262 v6, 20.2.2.31  */
80425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_TANH, /* ECMA-262 v6, 20.2.2.34  */
81425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_TRUNC, /* ECMA-262 v6, 20.2.2.35  */
82425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
83425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_ATAN2, /* ECMA-262 v5, 15.8.2.5 */ /* first routine with 2 arguments */
84425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
85425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_IMUL, /* ECMA-262 v6, 20.2.2.19  */
86425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
87425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_POW, /* ECMA-262 v5, 15.8.2.13 */ /* last routine with 1 or 2 arguments*/
88425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_MAX, /* ECMA-262 v5, 15.8.2.11 */
89425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_MIN, /* ECMA-262 v5, 15.8.2.12 */
90425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
91425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_HYPOT, /* ECMA-262 v6, 20.2.2.18  */
92425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
93425bb815Sopenharmony_ci  ECMA_MATH_OBJECT_RANDOM, /* ECMA-262 v5, 15.8.2.14 */
94425bb815Sopenharmony_ci};
95425bb815Sopenharmony_ci
96425bb815Sopenharmony_ci#define BUILTIN_INC_HEADER_NAME "ecma-builtin-math.inc.h"
97425bb815Sopenharmony_ci#define BUILTIN_UNDERSCORED_ID math
98425bb815Sopenharmony_ci#include "ecma-builtin-internal-routines-template.inc.h"
99425bb815Sopenharmony_ci
100425bb815Sopenharmony_ci/** \addtogroup ecma ECMA
101425bb815Sopenharmony_ci * @{
102425bb815Sopenharmony_ci *
103425bb815Sopenharmony_ci * \addtogroup ecmabuiltins
104425bb815Sopenharmony_ci * @{
105425bb815Sopenharmony_ci *
106425bb815Sopenharmony_ci * \addtogroup object ECMA Object object built-in
107425bb815Sopenharmony_ci * @{
108425bb815Sopenharmony_ci */
109425bb815Sopenharmony_ci
110425bb815Sopenharmony_ci/**
111425bb815Sopenharmony_ci * The Math object's 'max' 'min' routines.
112425bb815Sopenharmony_ci *
113425bb815Sopenharmony_ci * See also:
114425bb815Sopenharmony_ci *          ECMA-262 v5, 15.8.2.11
115425bb815Sopenharmony_ci *          ECMA-262 v5, 15.8.2.12
116425bb815Sopenharmony_ci *
117425bb815Sopenharmony_ci * @return ecma value
118425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value.
119425bb815Sopenharmony_ci */
120425bb815Sopenharmony_cistatic ecma_value_t
121425bb815Sopenharmony_ciecma_builtin_math_object_max_min (bool is_max, /**< 'max' or 'min' operation */
122425bb815Sopenharmony_ci                                  const ecma_value_t *arg, /**< arguments list */
123425bb815Sopenharmony_ci                                  ecma_length_t args_number) /**< number of arguments */
124425bb815Sopenharmony_ci{
125425bb815Sopenharmony_ci  ecma_number_t result_num = ecma_number_make_infinity (is_max);
126425bb815Sopenharmony_ci  bool nan_found = false;
127425bb815Sopenharmony_ci
128425bb815Sopenharmony_ci  while (args_number > 0)
129425bb815Sopenharmony_ci  {
130425bb815Sopenharmony_ci    ecma_number_t arg_num;
131425bb815Sopenharmony_ci
132425bb815Sopenharmony_ci    if (ecma_is_value_number (*arg))
133425bb815Sopenharmony_ci    {
134425bb815Sopenharmony_ci      arg_num = ecma_get_number_from_value (*arg);
135425bb815Sopenharmony_ci    }
136425bb815Sopenharmony_ci    else
137425bb815Sopenharmony_ci    {
138425bb815Sopenharmony_ci      ecma_value_t value = ecma_op_to_number (*arg);
139425bb815Sopenharmony_ci
140425bb815Sopenharmony_ci      if (ECMA_IS_VALUE_ERROR (value))
141425bb815Sopenharmony_ci      {
142425bb815Sopenharmony_ci        return value;
143425bb815Sopenharmony_ci      }
144425bb815Sopenharmony_ci
145425bb815Sopenharmony_ci      arg_num = ecma_get_number_from_value (value);
146425bb815Sopenharmony_ci
147425bb815Sopenharmony_ci      ecma_fast_free_value (value);
148425bb815Sopenharmony_ci    }
149425bb815Sopenharmony_ci
150425bb815Sopenharmony_ci    arg++;
151425bb815Sopenharmony_ci    args_number--;
152425bb815Sopenharmony_ci
153425bb815Sopenharmony_ci    if (JERRY_UNLIKELY (nan_found || ecma_number_is_nan (arg_num)))
154425bb815Sopenharmony_ci    {
155425bb815Sopenharmony_ci      nan_found = true;
156425bb815Sopenharmony_ci      continue;
157425bb815Sopenharmony_ci    }
158425bb815Sopenharmony_ci
159425bb815Sopenharmony_ci    if (ecma_number_is_zero (arg_num)
160425bb815Sopenharmony_ci        && ecma_number_is_zero (result_num))
161425bb815Sopenharmony_ci    {
162425bb815Sopenharmony_ci      bool is_negative = ecma_number_is_negative (arg_num);
163425bb815Sopenharmony_ci
164425bb815Sopenharmony_ci      if (is_max ? !is_negative : is_negative)
165425bb815Sopenharmony_ci      {
166425bb815Sopenharmony_ci        result_num = arg_num;
167425bb815Sopenharmony_ci      }
168425bb815Sopenharmony_ci    }
169425bb815Sopenharmony_ci    else
170425bb815Sopenharmony_ci    {
171425bb815Sopenharmony_ci      if (is_max ? (arg_num > result_num) : (arg_num < result_num))
172425bb815Sopenharmony_ci      {
173425bb815Sopenharmony_ci        result_num = arg_num;
174425bb815Sopenharmony_ci      }
175425bb815Sopenharmony_ci    }
176425bb815Sopenharmony_ci  }
177425bb815Sopenharmony_ci
178425bb815Sopenharmony_ci  if (JERRY_UNLIKELY (nan_found))
179425bb815Sopenharmony_ci  {
180425bb815Sopenharmony_ci    result_num = ecma_number_make_nan ();
181425bb815Sopenharmony_ci  }
182425bb815Sopenharmony_ci
183425bb815Sopenharmony_ci  return ecma_make_number_value (result_num);
184425bb815Sopenharmony_ci} /* ecma_builtin_math_object_max_min */
185425bb815Sopenharmony_ci
186425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
187425bb815Sopenharmony_ci/**
188425bb815Sopenharmony_ci * The Math object's 'hypot' routine
189425bb815Sopenharmony_ci *
190425bb815Sopenharmony_ci * See also:
191425bb815Sopenharmony_ci *          ECMA-262 v6, 20.2.2.18
192425bb815Sopenharmony_ci *
193425bb815Sopenharmony_ci * @return ecma value
194425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value.
195425bb815Sopenharmony_ci */
196425bb815Sopenharmony_cistatic ecma_value_t
197425bb815Sopenharmony_ciecma_builtin_math_object_hypot (const ecma_value_t *arg, /**< arguments list */
198425bb815Sopenharmony_ci                                ecma_length_t args_number) /**< number of arguments */
199425bb815Sopenharmony_ci{
200425bb815Sopenharmony_ci  if (args_number == 0)
201425bb815Sopenharmony_ci  {
202425bb815Sopenharmony_ci    return ecma_make_number_value (0.0);
203425bb815Sopenharmony_ci  }
204425bb815Sopenharmony_ci
205425bb815Sopenharmony_ci  bool nan_found = false;
206425bb815Sopenharmony_ci  bool inf_found = false;
207425bb815Sopenharmony_ci  ecma_number_t result_num = 0;
208425bb815Sopenharmony_ci
209425bb815Sopenharmony_ci  while (args_number > 0)
210425bb815Sopenharmony_ci  {
211425bb815Sopenharmony_ci    ecma_number_t arg_num;
212425bb815Sopenharmony_ci    if (ecma_is_value_number (*arg))
213425bb815Sopenharmony_ci    {
214425bb815Sopenharmony_ci      arg_num = ecma_get_number_from_value (*arg);
215425bb815Sopenharmony_ci    }
216425bb815Sopenharmony_ci    else
217425bb815Sopenharmony_ci    {
218425bb815Sopenharmony_ci      ecma_value_t value = ecma_op_to_number (*arg);
219425bb815Sopenharmony_ci      if (ECMA_IS_VALUE_ERROR (value))
220425bb815Sopenharmony_ci      {
221425bb815Sopenharmony_ci        return value;
222425bb815Sopenharmony_ci      }
223425bb815Sopenharmony_ci      arg_num = ecma_get_number_from_value (value);
224425bb815Sopenharmony_ci      ecma_fast_free_value (value);
225425bb815Sopenharmony_ci    }
226425bb815Sopenharmony_ci
227425bb815Sopenharmony_ci    arg++;
228425bb815Sopenharmony_ci    args_number--;
229425bb815Sopenharmony_ci
230425bb815Sopenharmony_ci    if (JERRY_UNLIKELY (inf_found || ecma_number_is_infinity (arg_num)))
231425bb815Sopenharmony_ci    {
232425bb815Sopenharmony_ci      inf_found = true;
233425bb815Sopenharmony_ci      continue;
234425bb815Sopenharmony_ci    }
235425bb815Sopenharmony_ci
236425bb815Sopenharmony_ci    if (JERRY_UNLIKELY (nan_found || ecma_number_is_nan (arg_num)))
237425bb815Sopenharmony_ci    {
238425bb815Sopenharmony_ci      nan_found = true;
239425bb815Sopenharmony_ci      continue;
240425bb815Sopenharmony_ci    }
241425bb815Sopenharmony_ci
242425bb815Sopenharmony_ci    result_num += arg_num * arg_num;
243425bb815Sopenharmony_ci  }
244425bb815Sopenharmony_ci
245425bb815Sopenharmony_ci  if (JERRY_UNLIKELY (inf_found))
246425bb815Sopenharmony_ci  {
247425bb815Sopenharmony_ci    return ecma_make_number_value (ecma_number_make_infinity (false));
248425bb815Sopenharmony_ci  }
249425bb815Sopenharmony_ci
250425bb815Sopenharmony_ci  if (JERRY_UNLIKELY (nan_found))
251425bb815Sopenharmony_ci  {
252425bb815Sopenharmony_ci    return ecma_make_nan_value ();
253425bb815Sopenharmony_ci  }
254425bb815Sopenharmony_ci
255425bb815Sopenharmony_ci  return ecma_make_number_value (sqrt (result_num));
256425bb815Sopenharmony_ci} /* ecma_builtin_math_object_hypot */
257425bb815Sopenharmony_ci
258425bb815Sopenharmony_ci/**
259425bb815Sopenharmony_ci * The Math object's 'trunc' routine
260425bb815Sopenharmony_ci *
261425bb815Sopenharmony_ci * See also:
262425bb815Sopenharmony_ci *          ECMA-262 v6, 20.2.2.35
263425bb815Sopenharmony_ci *
264425bb815Sopenharmony_ci * @return ecma number
265425bb815Sopenharmony_ci */
266425bb815Sopenharmony_cistatic ecma_number_t
267425bb815Sopenharmony_ciecma_builtin_math_object_trunc (ecma_number_t arg)
268425bb815Sopenharmony_ci{
269425bb815Sopenharmony_ci  if (ecma_number_is_nan (arg) || ecma_number_is_infinity (arg) || ecma_number_is_zero (arg))
270425bb815Sopenharmony_ci  {
271425bb815Sopenharmony_ci    return arg;
272425bb815Sopenharmony_ci  }
273425bb815Sopenharmony_ci
274425bb815Sopenharmony_ci  if ((arg > 0) && (arg < 1))
275425bb815Sopenharmony_ci  {
276425bb815Sopenharmony_ci    return (ecma_number_t) 0.0;
277425bb815Sopenharmony_ci  }
278425bb815Sopenharmony_ci
279425bb815Sopenharmony_ci  if ((arg < 0) && (arg > -1))
280425bb815Sopenharmony_ci  {
281425bb815Sopenharmony_ci    return (ecma_number_t) -0.0;
282425bb815Sopenharmony_ci  }
283425bb815Sopenharmony_ci
284425bb815Sopenharmony_ci  return (ecma_number_t) arg - fmod (arg, 1);
285425bb815Sopenharmony_ci} /* ecma_builtin_math_object_trunc */
286425bb815Sopenharmony_ci
287425bb815Sopenharmony_ci/**
288425bb815Sopenharmony_ci * The Math object's 'sign' routine
289425bb815Sopenharmony_ci *
290425bb815Sopenharmony_ci * See also:
291425bb815Sopenharmony_ci *          ECMA-262 v6, 20.2.2.29
292425bb815Sopenharmony_ci *
293425bb815Sopenharmony_ci * @return ecma number
294425bb815Sopenharmony_ci */
295425bb815Sopenharmony_cistatic ecma_number_t
296425bb815Sopenharmony_ciecma_builtin_math_object_sign (ecma_number_t arg)
297425bb815Sopenharmony_ci{
298425bb815Sopenharmony_ci  if (ecma_number_is_nan (arg) || ecma_number_is_zero (arg))
299425bb815Sopenharmony_ci  {
300425bb815Sopenharmony_ci    return arg;
301425bb815Sopenharmony_ci  }
302425bb815Sopenharmony_ci
303425bb815Sopenharmony_ci  if (ecma_number_is_negative (arg))
304425bb815Sopenharmony_ci  {
305425bb815Sopenharmony_ci    return (ecma_number_t) -1.0;
306425bb815Sopenharmony_ci  }
307425bb815Sopenharmony_ci
308425bb815Sopenharmony_ci  return (ecma_number_t) 1.0;
309425bb815Sopenharmony_ci} /* ecma_builtin_math_object_sign */
310425bb815Sopenharmony_ci
311425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
312425bb815Sopenharmony_ci
313425bb815Sopenharmony_ci/**
314425bb815Sopenharmony_ci * The Math object's 'random' routine.
315425bb815Sopenharmony_ci *
316425bb815Sopenharmony_ci * See also:
317425bb815Sopenharmony_ci *          ECMA-262 v5, 15.8.2.14
318425bb815Sopenharmony_ci *
319425bb815Sopenharmony_ci * @return ecma value
320425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value.
321425bb815Sopenharmony_ci */
322425bb815Sopenharmony_cistatic ecma_value_t
323425bb815Sopenharmony_ciecma_builtin_math_object_random (void)
324425bb815Sopenharmony_ci{
325425bb815Sopenharmony_ci  const ecma_number_t rand_max = (ecma_number_t) RAND_MAX;
326425bb815Sopenharmony_ci  const ecma_number_t rand_max_min_1 = (ecma_number_t) (RAND_MAX - 1);
327425bb815Sopenharmony_ci
328425bb815Sopenharmony_ci  return ecma_make_number_value (((ecma_number_t) rand ()) / rand_max * rand_max_min_1 / rand_max);
329425bb815Sopenharmony_ci} /* ecma_builtin_math_object_random */
330425bb815Sopenharmony_ci
331425bb815Sopenharmony_ci/**
332425bb815Sopenharmony_ci * Dispatcher for the built-in's routines.
333425bb815Sopenharmony_ci *
334425bb815Sopenharmony_ci * @return ecma value
335425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value.
336425bb815Sopenharmony_ci */
337425bb815Sopenharmony_ciecma_value_t
338425bb815Sopenharmony_ciecma_builtin_math_dispatch_routine (uint16_t builtin_routine_id, /**< built-in wide routine
339425bb815Sopenharmony_ci                                                                  *   identifier */
340425bb815Sopenharmony_ci                                    ecma_value_t this_arg, /**< 'this' argument value */
341425bb815Sopenharmony_ci                                    const ecma_value_t arguments_list[], /**< list of arguments
342425bb815Sopenharmony_ci                                                                          *   passed to routine */
343425bb815Sopenharmony_ci                                    ecma_length_t arguments_number) /**< length of arguments' list */
344425bb815Sopenharmony_ci{
345425bb815Sopenharmony_ci  JERRY_UNUSED (this_arg);
346425bb815Sopenharmony_ci
347425bb815Sopenharmony_ci  if (builtin_routine_id <= ECMA_MATH_OBJECT_POW)
348425bb815Sopenharmony_ci  {
349425bb815Sopenharmony_ci    ecma_number_t x = ecma_number_make_nan ();
350425bb815Sopenharmony_ci    ecma_number_t y = ecma_number_make_nan ();
351425bb815Sopenharmony_ci
352425bb815Sopenharmony_ci    if (arguments_number >= 1)
353425bb815Sopenharmony_ci    {
354425bb815Sopenharmony_ci      if (ecma_is_value_number (arguments_list[0]))
355425bb815Sopenharmony_ci      {
356425bb815Sopenharmony_ci        x = ecma_get_number_from_value (arguments_list[0]);
357425bb815Sopenharmony_ci      }
358425bb815Sopenharmony_ci      else
359425bb815Sopenharmony_ci      {
360425bb815Sopenharmony_ci        ecma_value_t value = ecma_op_to_number (arguments_list[0]);
361425bb815Sopenharmony_ci
362425bb815Sopenharmony_ci        if (ECMA_IS_VALUE_ERROR (value))
363425bb815Sopenharmony_ci        {
364425bb815Sopenharmony_ci          return value;
365425bb815Sopenharmony_ci        }
366425bb815Sopenharmony_ci
367425bb815Sopenharmony_ci        x = ecma_get_number_from_value (value);
368425bb815Sopenharmony_ci
369425bb815Sopenharmony_ci        ecma_fast_free_value (value);
370425bb815Sopenharmony_ci      }
371425bb815Sopenharmony_ci    }
372425bb815Sopenharmony_ci
373425bb815Sopenharmony_ci    if (builtin_routine_id >= ECMA_MATH_OBJECT_ATAN2
374425bb815Sopenharmony_ci        && arguments_number >= 2)
375425bb815Sopenharmony_ci    {
376425bb815Sopenharmony_ci      if (ecma_is_value_number (arguments_list[1]))
377425bb815Sopenharmony_ci      {
378425bb815Sopenharmony_ci        y = ecma_get_number_from_value (arguments_list[1]);
379425bb815Sopenharmony_ci      }
380425bb815Sopenharmony_ci      else
381425bb815Sopenharmony_ci      {
382425bb815Sopenharmony_ci        ecma_value_t value = ecma_op_to_number (arguments_list[1]);
383425bb815Sopenharmony_ci
384425bb815Sopenharmony_ci        if (ECMA_IS_VALUE_ERROR (value))
385425bb815Sopenharmony_ci        {
386425bb815Sopenharmony_ci          return value;
387425bb815Sopenharmony_ci        }
388425bb815Sopenharmony_ci
389425bb815Sopenharmony_ci        y = ecma_get_number_from_value (value);
390425bb815Sopenharmony_ci
391425bb815Sopenharmony_ci        ecma_fast_free_value (value);
392425bb815Sopenharmony_ci      }
393425bb815Sopenharmony_ci    }
394425bb815Sopenharmony_ci
395425bb815Sopenharmony_ci    switch (builtin_routine_id)
396425bb815Sopenharmony_ci    {
397425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_ABS:
398425bb815Sopenharmony_ci      {
399425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (fabs (x));
400425bb815Sopenharmony_ci        break;
401425bb815Sopenharmony_ci      }
402425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_ACOS:
403425bb815Sopenharmony_ci      {
404425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (acos (x));
405425bb815Sopenharmony_ci        break;
406425bb815Sopenharmony_ci      }
407425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_ASIN:
408425bb815Sopenharmony_ci      {
409425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (asin (x));
410425bb815Sopenharmony_ci        break;
411425bb815Sopenharmony_ci      }
412425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_ATAN:
413425bb815Sopenharmony_ci      {
414425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (atan (x));
415425bb815Sopenharmony_ci        break;
416425bb815Sopenharmony_ci      }
417425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_CEIL:
418425bb815Sopenharmony_ci      {
419425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (ceil (x));
420425bb815Sopenharmony_ci        break;
421425bb815Sopenharmony_ci      }
422425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_COS:
423425bb815Sopenharmony_ci      {
424425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (cos (x));
425425bb815Sopenharmony_ci        break;
426425bb815Sopenharmony_ci      }
427425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_EXP:
428425bb815Sopenharmony_ci      {
429425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (exp (x));
430425bb815Sopenharmony_ci        break;
431425bb815Sopenharmony_ci      }
432425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_FLOOR:
433425bb815Sopenharmony_ci      {
434425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (floor (x));
435425bb815Sopenharmony_ci        break;
436425bb815Sopenharmony_ci      }
437425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_LOG:
438425bb815Sopenharmony_ci      {
439425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (log (x));
440425bb815Sopenharmony_ci        break;
441425bb815Sopenharmony_ci      }
442425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
443425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_TRUNC:
444425bb815Sopenharmony_ci      {
445425bb815Sopenharmony_ci        x = ecma_builtin_math_object_trunc (x);
446425bb815Sopenharmony_ci        break;
447425bb815Sopenharmony_ci      }
448425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_SIGN:
449425bb815Sopenharmony_ci      {
450425bb815Sopenharmony_ci        x = ecma_builtin_math_object_sign (x);
451425bb815Sopenharmony_ci        break;
452425bb815Sopenharmony_ci      }
453425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
454425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_ROUND:
455425bb815Sopenharmony_ci      {
456425bb815Sopenharmony_ci        if (ecma_number_is_nan (x)
457425bb815Sopenharmony_ci            || ecma_number_is_zero (x)
458425bb815Sopenharmony_ci            || ecma_number_is_infinity (x)
459425bb815Sopenharmony_ci            || fmod (x, 1.0) == 0)
460425bb815Sopenharmony_ci        {
461425bb815Sopenharmony_ci          /* Do nothing. */
462425bb815Sopenharmony_ci        }
463425bb815Sopenharmony_ci        else if (ecma_number_is_negative (x)
464425bb815Sopenharmony_ci                 && x >= -ECMA_NUMBER_HALF)
465425bb815Sopenharmony_ci        {
466425bb815Sopenharmony_ci          x = -ECMA_NUMBER_ZERO;
467425bb815Sopenharmony_ci        }
468425bb815Sopenharmony_ci        else
469425bb815Sopenharmony_ci        {
470425bb815Sopenharmony_ci          const ecma_number_t up_half = x + ECMA_NUMBER_HALF;
471425bb815Sopenharmony_ci          const ecma_number_t down_half = x - ECMA_NUMBER_HALF;
472425bb815Sopenharmony_ci          const ecma_number_t up_rounded = up_half - ecma_op_number_remainder (up_half, ECMA_NUMBER_ONE);
473425bb815Sopenharmony_ci          const ecma_number_t down_rounded = down_half - ecma_op_number_remainder (down_half, ECMA_NUMBER_ONE);
474425bb815Sopenharmony_ci
475425bb815Sopenharmony_ci          if (up_rounded - x <= x - down_rounded)
476425bb815Sopenharmony_ci          {
477425bb815Sopenharmony_ci            x = up_rounded;
478425bb815Sopenharmony_ci          }
479425bb815Sopenharmony_ci          else
480425bb815Sopenharmony_ci          {
481425bb815Sopenharmony_ci            x = down_rounded;
482425bb815Sopenharmony_ci          }
483425bb815Sopenharmony_ci        }
484425bb815Sopenharmony_ci        break;
485425bb815Sopenharmony_ci      }
486425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_SIN:
487425bb815Sopenharmony_ci      {
488425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (sin (x));
489425bb815Sopenharmony_ci        break;
490425bb815Sopenharmony_ci      }
491425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_SQRT:
492425bb815Sopenharmony_ci      {
493425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (sqrt (x));
494425bb815Sopenharmony_ci        break;
495425bb815Sopenharmony_ci      }
496425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_TAN:
497425bb815Sopenharmony_ci      {
498425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (tan (x));
499425bb815Sopenharmony_ci        break;
500425bb815Sopenharmony_ci      }
501425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_ATAN2:
502425bb815Sopenharmony_ci      {
503425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (atan2 (x, y));
504425bb815Sopenharmony_ci        break;
505425bb815Sopenharmony_ci      }
506425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_POW:
507425bb815Sopenharmony_ci      {
508425bb815Sopenharmony_ci        x = ecma_number_pow (x, y);
509425bb815Sopenharmony_ci        break;
510425bb815Sopenharmony_ci      }
511425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
512425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_ACOSH:
513425bb815Sopenharmony_ci      {
514425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (acosh (x));
515425bb815Sopenharmony_ci        break;
516425bb815Sopenharmony_ci      }
517425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_ASINH:
518425bb815Sopenharmony_ci      {
519425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (asinh (x));
520425bb815Sopenharmony_ci        break;
521425bb815Sopenharmony_ci      }
522425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_ATANH:
523425bb815Sopenharmony_ci      {
524425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (atanh (x));
525425bb815Sopenharmony_ci        break;
526425bb815Sopenharmony_ci      }
527425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_CBRT:
528425bb815Sopenharmony_ci      {
529425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (cbrt (x));
530425bb815Sopenharmony_ci        break;
531425bb815Sopenharmony_ci      }
532425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_COSH:
533425bb815Sopenharmony_ci      {
534425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (cosh (x));
535425bb815Sopenharmony_ci        break;
536425bb815Sopenharmony_ci      }
537425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_EXPM1:
538425bb815Sopenharmony_ci      {
539425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (expm1 (x));
540425bb815Sopenharmony_ci        break;
541425bb815Sopenharmony_ci      }
542425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_LOG1P:
543425bb815Sopenharmony_ci      {
544425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (log1p (x));
545425bb815Sopenharmony_ci        break;
546425bb815Sopenharmony_ci      }
547425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_LOG10:
548425bb815Sopenharmony_ci      {
549425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (log10 (x));
550425bb815Sopenharmony_ci        break;
551425bb815Sopenharmony_ci      }
552425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_LOG2:
553425bb815Sopenharmony_ci      {
554425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (log2 (x));
555425bb815Sopenharmony_ci        break;
556425bb815Sopenharmony_ci      }
557425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_SINH:
558425bb815Sopenharmony_ci      {
559425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (sinh (x));
560425bb815Sopenharmony_ci        break;
561425bb815Sopenharmony_ci      }
562425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_TANH:
563425bb815Sopenharmony_ci      {
564425bb815Sopenharmony_ci        x = DOUBLE_TO_ECMA_NUMBER_T (tanh (x));
565425bb815Sopenharmony_ci        break;
566425bb815Sopenharmony_ci      }
567425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_CLZ32:
568425bb815Sopenharmony_ci      {
569425bb815Sopenharmony_ci        uint32_t n = ecma_number_to_uint32 (x);
570425bb815Sopenharmony_ci#if defined (__GNUC__) || defined (__clang__)
571425bb815Sopenharmony_ci        x = n ? __builtin_clz (n) : 32;
572425bb815Sopenharmony_ci#elif defined (WIN32)
573425bb815Sopenharmony_ci        unsigned long ret;
574425bb815Sopenharmony_ci        x = _BitScanReverse (&ret, n) ? 31 - ret : 32;
575425bb815Sopenharmony_ci#else
576425bb815Sopenharmony_ci        x = 32;
577425bb815Sopenharmony_ci        for (int i = 31; i >= 0; i--)
578425bb815Sopenharmony_ci        {
579425bb815Sopenharmony_ci          if (n >> i)
580425bb815Sopenharmony_ci          {
581425bb815Sopenharmony_ci            x = 31 - i;
582425bb815Sopenharmony_ci            break;
583425bb815Sopenharmony_ci          }
584425bb815Sopenharmony_ci        }
585425bb815Sopenharmony_ci#endif
586425bb815Sopenharmony_ci        break;
587425bb815Sopenharmony_ci      }
588425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_FROUND:
589425bb815Sopenharmony_ci      {
590425bb815Sopenharmony_ci        x = (float) x;
591425bb815Sopenharmony_ci        break;
592425bb815Sopenharmony_ci      }
593425bb815Sopenharmony_ci      case ECMA_MATH_OBJECT_IMUL:
594425bb815Sopenharmony_ci      {
595425bb815Sopenharmony_ci        x = (int32_t) (ecma_number_to_uint32 (x) * ecma_number_to_uint32 (y));
596425bb815Sopenharmony_ci        break;
597425bb815Sopenharmony_ci      }
598425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
599425bb815Sopenharmony_ci    }
600425bb815Sopenharmony_ci    return ecma_make_number_value (x);
601425bb815Sopenharmony_ci  } /* if (builtin_routine_id <= ECMA_MATH_OBJECT_POW) */
602425bb815Sopenharmony_ci
603425bb815Sopenharmony_ci  if (builtin_routine_id <= ECMA_MATH_OBJECT_MIN)
604425bb815Sopenharmony_ci  {
605425bb815Sopenharmony_ci    return ecma_builtin_math_object_max_min (builtin_routine_id == ECMA_MATH_OBJECT_MAX,
606425bb815Sopenharmony_ci                                             arguments_list,
607425bb815Sopenharmony_ci                                             arguments_number);
608425bb815Sopenharmony_ci  }
609425bb815Sopenharmony_ci
610425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
611425bb815Sopenharmony_ci  if (builtin_routine_id == ECMA_MATH_OBJECT_HYPOT)
612425bb815Sopenharmony_ci  {
613425bb815Sopenharmony_ci    return ecma_builtin_math_object_hypot (arguments_list, arguments_number);
614425bb815Sopenharmony_ci  }
615425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
616425bb815Sopenharmony_ci
617425bb815Sopenharmony_ci  JERRY_ASSERT (builtin_routine_id == ECMA_MATH_OBJECT_RANDOM);
618425bb815Sopenharmony_ci
619425bb815Sopenharmony_ci  return ecma_builtin_math_object_random ();
620425bb815Sopenharmony_ci} /* ecma_builtin_math_dispatch_routine */
621425bb815Sopenharmony_ci
622425bb815Sopenharmony_ci/**
623425bb815Sopenharmony_ci * @}
624425bb815Sopenharmony_ci * @}
625425bb815Sopenharmony_ci * @}
626425bb815Sopenharmony_ci */
627425bb815Sopenharmony_ci
628425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_BUILTIN_MATH) */
629