1/* Copyright JS Foundation and other contributors, http://js.foundation
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <math.h>
17
18#include "ecma-alloc.h"
19#include "ecma-builtins.h"
20#include "ecma-conversion.h"
21#include "ecma-exceptions.h"
22#include "ecma-gc.h"
23#include "ecma-globals.h"
24#include "ecma-helpers.h"
25#include "ecma-number-object.h"
26#include "ecma-objects.h"
27#include "ecma-try-catch-macro.h"
28#include "jrt.h"
29
30#if ENABLED (JERRY_BUILTIN_NUMBER)
31
32#define ECMA_BUILTINS_INTERNAL
33#include "ecma-builtins-internal.h"
34
35#define BUILTIN_INC_HEADER_NAME "ecma-builtin-number.inc.h"
36#define BUILTIN_UNDERSCORED_ID number
37#include "ecma-builtin-internal-routines-template.inc.h"
38
39/** \addtogroup ecma ECMA
40 * @{
41 *
42 * \addtogroup ecmabuiltins
43 * @{
44 *
45 * \addtogroup number ECMA Number object built-in
46 * @{
47 */
48
49/**
50 * Handle calling [[Call]] of built-in Number object
51 *
52 * @return ecma value
53 */
54ecma_value_t
55ecma_builtin_number_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
56                                   ecma_length_t arguments_list_len) /**< number of arguments */
57{
58  JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
59
60  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
61
62  if (arguments_list_len == 0)
63  {
64    ret_value = ecma_make_integer_value (0);
65  }
66  else
67  {
68    ret_value = ecma_op_to_number (arguments_list_p[0]);
69  }
70
71  return ret_value;
72} /* ecma_builtin_number_dispatch_call */
73
74/**
75 * Handle calling [[Construct]] of built-in Number object
76 *
77 * @return ecma value
78 */
79ecma_value_t
80ecma_builtin_number_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
81                                        ecma_length_t arguments_list_len) /**< number of arguments */
82{
83  JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
84
85  if (arguments_list_len == 0)
86  {
87    ecma_value_t completion = ecma_op_create_number_object (ecma_make_integer_value (0));
88    return completion;
89  }
90  else
91  {
92    return ecma_op_create_number_object (arguments_list_p[0]);
93  }
94} /* ecma_builtin_number_dispatch_construct */
95
96#if ENABLED (JERRY_ES2015)
97
98/**
99 * The Number object 'isFinite' routine
100 *
101 * See also:
102 *          ECMA-262 v6, 20.1.2.2
103 *
104 * @return ecma value
105 *         Returned value must be freed with ecma_free_value.
106 */
107static ecma_value_t
108ecma_builtin_number_object_is_finite (ecma_value_t this_arg, /**< this argument */
109                                      ecma_value_t arg) /**< routine's argument */
110{
111  JERRY_UNUSED (this_arg);
112
113  if (ecma_is_value_number (arg))
114  {
115    ecma_number_t num = ecma_get_number_from_value (arg);
116    if (!(ecma_number_is_nan (num) || ecma_number_is_infinity (num)))
117    {
118      return ECMA_VALUE_TRUE;
119    }
120  }
121  return ECMA_VALUE_FALSE;
122} /* ecma_builtin_number_object_is_finite */
123
124/**
125 * The Number object 'isNan' routine
126 *
127 * See also:
128 *          ECMA-262 v6, 20.1.2.4
129 *
130 * @return ecma value
131 *         Returned value must be freed with ecma_free_value.
132 */
133static ecma_value_t
134ecma_builtin_number_object_is_nan (ecma_value_t this_arg, /**< this argument */
135                                   ecma_value_t arg) /**< routine's argument */
136{
137  JERRY_UNUSED (this_arg);
138
139  if (ecma_is_value_number (arg))
140  {
141    ecma_number_t num_val = ecma_get_number_from_value (arg);
142
143    if (ecma_number_is_nan (num_val))
144    {
145      return ECMA_VALUE_TRUE;
146    }
147  }
148  return ECMA_VALUE_FALSE;
149} /* ecma_builtin_number_object_is_nan */
150
151/**
152 * The Number object 'isInteger' routine
153 *
154 * See also:
155 *          ECMA-262 v6, 20.1.2.3
156 *
157 * @return ecma value
158 *         Returned value must be freed with ecma_free_value.
159 */
160static ecma_value_t
161ecma_builtin_number_object_is_integer (ecma_value_t this_arg, /**< this argument */
162                                       ecma_value_t arg) /**< routine's argument */
163{
164  JERRY_UNUSED (this_arg);
165  if (!ecma_is_value_number (arg))
166  {
167    return ECMA_VALUE_FALSE;
168  }
169
170  ecma_number_t num = ecma_get_number_from_value (arg);
171
172  if (ecma_number_is_nan (num) || ecma_number_is_infinity (num))
173  {
174    return ECMA_VALUE_FALSE;
175  }
176
177  ecma_number_t int_num;
178  ecma_op_to_integer (arg, &int_num);
179
180  if (int_num != num)
181  {
182    return ECMA_VALUE_FALSE;
183  }
184
185  return ECMA_VALUE_TRUE;
186} /* ecma_builtin_number_object_is_integer */
187
188/**
189 * The Number object 'isSafeInteger' routine
190 *
191 * See also:
192 *          ECMA-262 v6, 20.1.2.3
193 *
194 * @return ecma value
195 *         Returned value must be freed with ecma_free_value.
196 */
197static ecma_value_t
198ecma_builtin_number_object_is_safe_integer (ecma_value_t this_arg, /**< this argument */
199                                            ecma_value_t arg) /**< routine's argument */
200{
201  JERRY_UNUSED (this_arg);
202
203  if (!ecma_is_value_number (arg))
204  {
205    return ECMA_VALUE_FALSE;
206  }
207
208  ecma_number_t num = ecma_get_number_from_value (arg);
209
210  if (ecma_number_is_nan (num) || ecma_number_is_infinity (num))
211  {
212    return ECMA_VALUE_FALSE;
213  }
214
215  ecma_number_t int_num = ecma_number_trunc (num);
216
217  if (int_num == num && fabs (int_num) <= ECMA_NUMBER_MAX_SAFE_INTEGER)
218  {
219    return ECMA_VALUE_TRUE;
220  }
221
222  return ECMA_VALUE_FALSE;
223} /* ecma_builtin_number_object_is_safe_integer */
224
225#endif /* ENABLED (JERRY_ES2015) */
226
227/**
228 * @}
229 * @}
230 * @}
231 */
232
233#endif /* ENABLED (JERRY_BUILTIN_NUMBER) */
234