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 */
54 ecma_value_t
ecma_builtin_number_dispatch_call(const ecma_value_t * arguments_list_p,ecma_length_t arguments_list_len)55 ecma_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 */
79 ecma_value_t
ecma_builtin_number_dispatch_construct(const ecma_value_t * arguments_list_p,ecma_length_t arguments_list_len)80 ecma_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 */
107 static ecma_value_t
ecma_builtin_number_object_is_finite(ecma_value_t this_arg,ecma_value_t arg)108 ecma_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 */
133 static ecma_value_t
ecma_builtin_number_object_is_nan(ecma_value_t this_arg,ecma_value_t arg)134 ecma_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 */
160 static ecma_value_t
ecma_builtin_number_object_is_integer(ecma_value_t this_arg,ecma_value_t arg)161 ecma_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 */
197 static ecma_value_t
ecma_builtin_number_object_is_safe_integer(ecma_value_t this_arg,ecma_value_t arg)198 ecma_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