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