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 "ecma-alloc.h"
17 #include "ecma-exceptions.h"
18 #include "ecma-gc.h"
19 #include "ecma-globals.h"
20 #include "ecma-helpers.h"
21 #include "jrt.h"
22 #include "jrt-bit-fields.h"
23 #include "vm-defines.h"
24
25 #include "ecma-function-object.h"
26
27 JERRY_STATIC_ASSERT (ECMA_TYPE___MAX <= ECMA_VALUE_TYPE_MASK,
28 ecma_types_must_be_less_than_mask);
29
30 JERRY_STATIC_ASSERT ((ECMA_VALUE_TYPE_MASK + 1) == (1 << ECMA_VALUE_SHIFT),
31 ecma_value_part_must_start_after_flags);
32
33 JERRY_STATIC_ASSERT (ECMA_VALUE_SHIFT <= JMEM_ALIGNMENT_LOG,
34 ecma_value_shift_must_be_less_than_or_equal_than_mem_alignment_log);
35
36 JERRY_STATIC_ASSERT (sizeof (jmem_cpointer_t) <= sizeof (ecma_value_t),
37 size_of_jmem_cpointer_t_must_be_less_or_equal_to_the_size_of_ecma_value_t);
38
39 JERRY_STATIC_ASSERT (sizeof (jmem_cpointer_t) <= sizeof (jmem_cpointer_tag_t),
40 size_of_jmem_cpointer_t_must_be_less_or_equal_to_the_size_of_jmem_cpointer_tag_t);
41
42 #ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
43
44 /* cppcheck-suppress zerodiv */
45 JERRY_STATIC_ASSERT (sizeof (uintptr_t) <= sizeof (ecma_value_t),
46 uintptr_t_must_fit_in_ecma_value_t);
47
48 #else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
49
50 JERRY_STATIC_ASSERT (sizeof (uintptr_t) > sizeof (ecma_value_t),
51 uintptr_t_must_not_fit_in_ecma_value_t);
52
53 #endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
54
55 JERRY_STATIC_ASSERT ((ECMA_VALUE_FALSE | (1 << ECMA_DIRECT_SHIFT)) == ECMA_VALUE_TRUE
56 && ECMA_VALUE_FALSE != ECMA_VALUE_TRUE,
57 only_the_lowest_bit_must_be_different_for_simple_value_true_and_false);
58
59 /** \addtogroup ecma ECMA
60 * @{
61 *
62 * \addtogroup ecmahelpers Helpers for operations with ECMA data types
63 * @{
64 */
65
66 /**
67 * Get type field of ecma value
68 *
69 * @return type field
70 */
71 extern inline ecma_type_t JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_get_value_type_field(ecma_value_t value)72 ecma_get_value_type_field (ecma_value_t value) /**< ecma value */
73 {
74 return value & ECMA_VALUE_TYPE_MASK;
75 } /* ecma_get_value_type_field */
76
77 /**
78 * Convert a pointer into an ecma value.
79 *
80 * @return ecma value
81 */
82 static inline ecma_value_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_pointer_to_ecma_value(const void * ptr)83 ecma_pointer_to_ecma_value (const void *ptr) /**< pointer */
84 {
85 #ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
86
87 JERRY_ASSERT (ptr != NULL);
88 uintptr_t uint_ptr = (uintptr_t) ptr;
89 JERRY_ASSERT ((uint_ptr & ECMA_VALUE_TYPE_MASK) == 0);
90 return (ecma_value_t) uint_ptr;
91
92 #else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
93
94 jmem_cpointer_t ptr_cp;
95 ECMA_SET_NON_NULL_POINTER (ptr_cp, ptr);
96 return ((ecma_value_t) ptr_cp) << ECMA_VALUE_SHIFT;
97
98 #endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
99 } /* ecma_pointer_to_ecma_value */
100
101 /**
102 * Get a pointer from an ecma value
103 *
104 * @return pointer
105 */
106 static inline void * JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_get_pointer_from_ecma_value(ecma_value_t value)107 ecma_get_pointer_from_ecma_value (ecma_value_t value) /**< value */
108 {
109 #ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
110 void *ptr = (void *) (uintptr_t) ((value) & ~ECMA_VALUE_TYPE_MASK);
111 JERRY_ASSERT (ptr != NULL);
112 return ptr;
113 #else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
114 return ECMA_GET_NON_NULL_POINTER (void, value >> ECMA_VALUE_SHIFT);
115 #endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
116 } /* ecma_get_pointer_from_ecma_value */
117
118 /**
119 * Check if the value is direct ecma-value.
120 *
121 * @return true - if the value is a direct value,
122 * false - otherwise
123 */
124 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_direct(ecma_value_t value)125 ecma_is_value_direct (ecma_value_t value) /**< ecma value */
126 {
127 return (ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT);
128 } /* ecma_is_value_direct */
129
130 /**
131 * Check if the value is simple ecma-value.
132 *
133 * @return true - if the value is a simple value,
134 * false - otherwise
135 */
136 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_simple(ecma_value_t value)137 ecma_is_value_simple (ecma_value_t value) /**< ecma value */
138 {
139 return (value & ECMA_DIRECT_TYPE_MASK) == ECMA_DIRECT_TYPE_SIMPLE_VALUE;
140 } /* ecma_is_value_simple */
141
142 /**
143 * Check whether the value is a given simple value.
144 *
145 * @return true - if the value is equal to the given simple value,
146 * false - otherwise
147 */
148 static inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_equal_to_simple_value(ecma_value_t value,ecma_value_t simple_value)149 ecma_is_value_equal_to_simple_value (ecma_value_t value, /**< ecma value */
150 ecma_value_t simple_value) /**< simple value */
151 {
152 return value == simple_value;
153 } /* ecma_is_value_equal_to_simple_value */
154
155 /**
156 * Check if the value is empty.
157 *
158 * @return true - if the value contains implementation-defined empty simple value,
159 * false - otherwise
160 */
161 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_empty(ecma_value_t value)162 ecma_is_value_empty (ecma_value_t value) /**< ecma value */
163 {
164 return ecma_is_value_equal_to_simple_value (value, ECMA_VALUE_EMPTY);
165 } /* ecma_is_value_empty */
166
167 /**
168 * Check if the value is undefined.
169 *
170 * @return true - if the value contains ecma-undefined simple value,
171 * false - otherwise
172 */
173 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_undefined(ecma_value_t value)174 ecma_is_value_undefined (ecma_value_t value) /**< ecma value */
175 {
176 return ecma_is_value_equal_to_simple_value (value, ECMA_VALUE_UNDEFINED);
177 } /* ecma_is_value_undefined */
178
179 /**
180 * Check if the value is null.
181 *
182 * @return true - if the value contains ecma-null simple value,
183 * false - otherwise
184 */
185 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_null(ecma_value_t value)186 ecma_is_value_null (ecma_value_t value) /**< ecma value */
187 {
188 return ecma_is_value_equal_to_simple_value (value, ECMA_VALUE_NULL);
189 } /* ecma_is_value_null */
190
191 /**
192 * Check if the value is boolean.
193 *
194 * @return true - if the value contains ecma-true or ecma-false simple values,
195 * false - otherwise
196 */
197 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_boolean(ecma_value_t value)198 ecma_is_value_boolean (ecma_value_t value) /**< ecma value */
199 {
200 return ecma_is_value_true (value | (1 << ECMA_DIRECT_SHIFT));
201 } /* ecma_is_value_boolean */
202
203 /**
204 * Check if the value is true.
205 *
206 * @return true - if the value contains ecma-true simple value,
207 * false - otherwise
208 */
209 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_true(ecma_value_t value)210 ecma_is_value_true (ecma_value_t value) /**< ecma value */
211 {
212 return ecma_is_value_equal_to_simple_value (value, ECMA_VALUE_TRUE);
213 } /* ecma_is_value_true */
214
215 /**
216 * Check if the value is false.
217 *
218 * @return true - if the value contains ecma-false simple value,
219 * false - otherwise
220 */
221 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_false(ecma_value_t value)222 ecma_is_value_false (ecma_value_t value) /**< ecma value */
223 {
224 return ecma_is_value_equal_to_simple_value (value, ECMA_VALUE_FALSE);
225 } /* ecma_is_value_false */
226
227 /**
228 * Check if the value is not found.
229 *
230 * @return true - if the value contains ecma-not-found simple value,
231 * false - otherwise
232 */
233 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_found(ecma_value_t value)234 ecma_is_value_found (ecma_value_t value) /**< ecma value */
235 {
236 return value != ECMA_VALUE_NOT_FOUND;
237 } /* ecma_is_value_found */
238
239 /**
240 * Check if the value is array hole.
241 *
242 * @return true - if the value contains ecma-array-hole simple value,
243 * false - otherwise
244 */
245 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_array_hole(ecma_value_t value)246 ecma_is_value_array_hole (ecma_value_t value) /**< ecma value */
247 {
248 return ecma_is_value_equal_to_simple_value (value, ECMA_VALUE_ARRAY_HOLE);
249 } /* ecma_is_value_array_hole */
250
251 /**
252 * Check if the value is integer ecma-number.
253 *
254 * @return true - if the value contains an integer ecma-number value,
255 * false - otherwise
256 */
257 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_integer_number(ecma_value_t value)258 ecma_is_value_integer_number (ecma_value_t value) /**< ecma value */
259 {
260 return (value & ECMA_DIRECT_TYPE_MASK) == ECMA_DIRECT_TYPE_INTEGER_VALUE;
261 } /* ecma_is_value_integer_number */
262
263 /**
264 * Check if both values are integer ecma-numbers.
265 *
266 * @return true - if both values contain integer ecma-number values,
267 * false - otherwise
268 */
269 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_are_values_integer_numbers(ecma_value_t first_value,ecma_value_t second_value)270 ecma_are_values_integer_numbers (ecma_value_t first_value, /**< first ecma value */
271 ecma_value_t second_value) /**< second ecma value */
272 {
273 JERRY_STATIC_ASSERT (ECMA_DIRECT_TYPE_INTEGER_VALUE == 0,
274 ecma_direct_type_integer_value_must_be_zero);
275
276 return ((first_value | second_value) & ECMA_DIRECT_TYPE_MASK) == ECMA_DIRECT_TYPE_INTEGER_VALUE;
277 } /* ecma_are_values_integer_numbers */
278
279 /**
280 * Check if the value is floating-point ecma-number.
281 *
282 * @return true - if the value contains a floating-point ecma-number value,
283 * false - otherwise
284 */
285 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_float_number(ecma_value_t value)286 ecma_is_value_float_number (ecma_value_t value) /**< ecma value */
287 {
288 return (ecma_get_value_type_field (value) == ECMA_TYPE_FLOAT);
289 } /* ecma_is_value_float_number */
290
291 /**
292 * Check if the value is ecma-number.
293 *
294 * @return true - if the value contains ecma-number value,
295 * false - otherwise
296 */
297 extern inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_number(ecma_value_t value)298 ecma_is_value_number (ecma_value_t value) /**< ecma value */
299 {
300 return (ecma_is_value_integer_number (value)
301 || ecma_is_value_float_number (value));
302 } /* ecma_is_value_number */
303
304 JERRY_STATIC_ASSERT ((ECMA_TYPE_STRING | 0x4) == ECMA_TYPE_DIRECT_STRING,
305 ecma_type_string_and_direct_string_must_have_one_bit_difference);
306
307 /**
308 * Check if the value is ecma-string.
309 *
310 * @return true - if the value contains ecma-string value,
311 * false - otherwise
312 */
313 extern inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_string(ecma_value_t value)314 ecma_is_value_string (ecma_value_t value) /**< ecma value */
315 {
316 return ((value & (ECMA_VALUE_TYPE_MASK - 0x4)) == ECMA_TYPE_STRING);
317 } /* ecma_is_value_string */
318
319 #if ENABLED (JERRY_ES2015)
320 /**
321 * Check if the value is symbol.
322 *
323 * @return true - if the value contains symbol value,
324 * false - otherwise
325 */
326 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_symbol(ecma_value_t value)327 ecma_is_value_symbol (ecma_value_t value) /**< ecma value */
328 {
329 return (ecma_get_value_type_field (value) == ECMA_TYPE_SYMBOL);
330 } /* ecma_is_value_symbol */
331 #endif /* ENABLED (JERRY_ES2015) */
332
333 /**
334 * Check if the value can be property name.
335 *
336 * @return true - if the value can be property name value,
337 * false - otherwise
338 */
339 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_prop_name(ecma_value_t value)340 ecma_is_value_prop_name (ecma_value_t value) /**< ecma value */
341 {
342 #if ENABLED (JERRY_ES2015)
343 return ecma_is_value_string (value) || ecma_is_value_symbol (value);
344 #else /* !ENABLED (JERRY_ES2015) */
345 return ecma_is_value_string (value);
346 #endif /* ENABLED (JERRY_ES2015) */
347 } /* ecma_is_value_prop_name */
348
349 /**
350 * Check if the value is direct ecma-string.
351 *
352 * @return true - if the value contains direct ecma-string value,
353 * false - otherwise
354 */
355 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_direct_string(ecma_value_t value)356 ecma_is_value_direct_string (ecma_value_t value) /**< ecma value */
357 {
358 return (ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT_STRING);
359 } /* ecma_is_value_direct_string */
360
361 /**
362 * Check if the value is non-direct ecma-string.
363 *
364 * @return true - if the value contains non-direct ecma-string value,
365 * false - otherwise
366 */
367 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_non_direct_string(ecma_value_t value)368 ecma_is_value_non_direct_string (ecma_value_t value) /**< ecma value */
369 {
370 return (ecma_get_value_type_field (value) == ECMA_TYPE_STRING);
371 } /* ecma_is_value_non_direct_string */
372
373 /**
374 * Check if the value is object.
375 *
376 * @return true - if the value contains object value,
377 * false - otherwise
378 */
379 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_object(ecma_value_t value)380 ecma_is_value_object (ecma_value_t value) /**< ecma value */
381 {
382 return (ecma_get_value_type_field (value) == ECMA_TYPE_OBJECT);
383 } /* ecma_is_value_object */
384
385 /**
386 * Check if the value is error reference.
387 *
388 * @return true - if the value contains an error reference,
389 * false - otherwise
390 */
391 inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_error_reference(ecma_value_t value)392 ecma_is_value_error_reference (ecma_value_t value) /**< ecma value */
393 {
394 return (ecma_get_value_type_field (value) == ECMA_TYPE_ERROR);
395 } /* ecma_is_value_error_reference */
396
397 /**
398 * Debug assertion that specified value's type is one of ECMA-defined
399 * script-visible types, i.e.: undefined, null, boolean, number, string, object.
400 */
401 void
ecma_check_value_type_is_spec_defined(ecma_value_t value)402 ecma_check_value_type_is_spec_defined (ecma_value_t value) /**< ecma value */
403 {
404 JERRY_ASSERT (ecma_is_value_undefined (value)
405 || ecma_is_value_null (value)
406 || ecma_is_value_boolean (value)
407 || ecma_is_value_number (value)
408 || ecma_is_value_string (value)
409 || ECMA_ASSERT_VALUE_IS_SYMBOL (value)
410 || ecma_is_value_object (value));
411 } /* ecma_check_value_type_is_spec_defined */
412
413 /**
414 * Checks if the given argument is an array or not.
415 *
416 * @return ECMA_VALUE_ERROR- if the operation fails
417 * ECMA_VALUE_{TRUE/FALSE} - depends on whether 'arg' is an array object
418 */
419 ecma_value_t
ecma_is_value_array(ecma_value_t arg)420 ecma_is_value_array (ecma_value_t arg) /**< argument */
421 {
422 if (!ecma_is_value_object (arg))
423 {
424 return ECMA_VALUE_FALSE;
425 }
426
427 ecma_object_t *arg_obj_p = ecma_get_object_from_value (arg);
428
429 if (ecma_get_object_type (arg_obj_p) == ECMA_OBJECT_TYPE_ARRAY)
430 {
431 return ECMA_VALUE_TRUE;
432 }
433
434 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
435 if (ECMA_OBJECT_IS_PROXY (arg_obj_p))
436 {
437 ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) arg_obj_p;
438
439 if (proxy_obj_p->handler == ECMA_VALUE_NULL)
440 {
441 return ecma_raise_type_error (ECMA_ERR_MSG ("Cannot perform 'IsArray' on the given proxy "
442 "because handler is null"));
443 }
444
445 return ecma_is_value_array (proxy_obj_p->target);
446 }
447 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
448
449 return ECMA_VALUE_FALSE;
450 } /* ecma_is_value_array */
451
452 /**
453 * Creates an ecma value from the given raw boolean.
454 *
455 * @return boolean ecma_value
456 */
457 inline ecma_value_t JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_make_boolean_value(bool boolean_value)458 ecma_make_boolean_value (bool boolean_value) /**< raw bool value from which the ecma value will be created */
459 {
460 return boolean_value ? ECMA_VALUE_TRUE : ECMA_VALUE_FALSE;
461 } /* ecma_make_boolean_value */
462
463 /**
464 * Encode an integer number into an ecma-value without allocating memory
465 *
466 * Note:
467 * The value must fit into the range of allowed ecma integer values
468 *
469 * @return ecma-value
470 */
471 inline ecma_value_t JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_make_integer_value(ecma_integer_value_t integer_value)472 ecma_make_integer_value (ecma_integer_value_t integer_value) /**< integer number to be encoded */
473 {
474 JERRY_ASSERT (ECMA_IS_INTEGER_NUMBER (integer_value));
475
476 return (((ecma_value_t) integer_value) << ECMA_DIRECT_SHIFT) | ECMA_DIRECT_TYPE_INTEGER_VALUE;
477 } /* ecma_make_integer_value */
478
479 /**
480 * Allocate and initialize a new float number without checks.
481 *
482 * @return ecma-value
483 */
484 static ecma_value_t
ecma_create_float_number(ecma_number_t ecma_number)485 ecma_create_float_number (ecma_number_t ecma_number) /**< value of the float number */
486 {
487 ecma_number_t *ecma_num_p = ecma_alloc_number ();
488
489 *ecma_num_p = ecma_number;
490
491 return ecma_pointer_to_ecma_value (ecma_num_p) | ECMA_TYPE_FLOAT;
492 } /* ecma_create_float_number */
493
494 /**
495 * Encode float number without checks.
496 *
497 * @return ecma-value
498 */
499 ecma_value_t
ecma_make_float_value(ecma_number_t * ecma_num_p)500 ecma_make_float_value (ecma_number_t *ecma_num_p) /**< pointer to the float number */
501 {
502 return ecma_pointer_to_ecma_value (ecma_num_p) | ECMA_TYPE_FLOAT;
503 } /* ecma_make_float_value */
504
505 /**
506 * Create a new NaN value.
507 *
508 * @return ecma-value
509 */
510 extern inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
ecma_make_nan_value(void)511 ecma_make_nan_value (void)
512 {
513 return ecma_create_float_number (ecma_number_make_nan ());
514 } /* ecma_make_nan_value */
515
516 /**
517 * Checks whether the passed number is +0.0
518 *
519 * @return true, if it is +0.0, false otherwise
520 */
521 static inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_number_equal_to_positive_zero(ecma_number_t ecma_number)522 ecma_is_number_equal_to_positive_zero (ecma_number_t ecma_number) /**< number */
523 {
524 ecma_number_accessor_t u;
525 u.as_ecma_number_t = ecma_number;
526 #if !ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
527 return u.as_uint32_t == 0;
528 #else /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
529 return u.as_uint64_t == 0;
530 #endif /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
531 } /* ecma_is_number_equal_to_positive_zero */
532
533 /**
534 * Encode a number into an ecma-value
535 *
536 * @return ecma-value
537 */
538 ecma_value_t
ecma_make_number_value(ecma_number_t ecma_number)539 ecma_make_number_value (ecma_number_t ecma_number) /**< number to be encoded */
540 {
541 ecma_integer_value_t integer_value = (ecma_integer_value_t) ecma_number;
542
543 if ((ecma_number_t) integer_value == ecma_number
544 && ((integer_value == 0) ? ecma_is_number_equal_to_positive_zero (ecma_number)
545 : ECMA_IS_INTEGER_NUMBER (integer_value)))
546 {
547 return ecma_make_integer_value (integer_value);
548 }
549
550 return ecma_create_float_number (ecma_number);
551 } /* ecma_make_number_value */
552
553 /**
554 * Encode an int32 number into an ecma-value
555 *
556 * @return ecma-value
557 */
558 ecma_value_t
ecma_make_int32_value(int32_t int32_number)559 ecma_make_int32_value (int32_t int32_number) /**< int32 number to be encoded */
560 {
561 if (ECMA_IS_INTEGER_NUMBER (int32_number))
562 {
563 return ecma_make_integer_value ((ecma_integer_value_t) int32_number);
564 }
565
566 return ecma_create_float_number ((ecma_number_t) int32_number);
567 } /* ecma_make_int32_value */
568
569 /**
570 * Encode an unsigned int32 number into an ecma-value
571 *
572 * @return ecma-value
573 */
574 ecma_value_t
ecma_make_uint32_value(uint32_t uint32_number)575 ecma_make_uint32_value (uint32_t uint32_number) /**< uint32 number to be encoded */
576 {
577 if (uint32_number <= ECMA_INTEGER_NUMBER_MAX)
578 {
579 return ecma_make_integer_value ((ecma_integer_value_t) uint32_number);
580 }
581
582 return ecma_create_float_number ((ecma_number_t) uint32_number);
583 } /* ecma_make_uint32_value */
584
585 /**
586 * String value constructor
587 *
588 * @return ecma-value representation of the string argument
589 */
590 inline ecma_value_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_make_string_value(const ecma_string_t * ecma_string_p)591 ecma_make_string_value (const ecma_string_t *ecma_string_p) /**< string to reference in value */
592 {
593 JERRY_ASSERT (ecma_string_p != NULL);
594 #if ENABLED (JERRY_ES2015)
595 JERRY_ASSERT (!ecma_prop_name_is_symbol ((ecma_string_t *) ecma_string_p));
596 #endif /* ENABLED (JERRY_ES2015) */
597
598 if ((((uintptr_t) ecma_string_p) & ECMA_VALUE_TYPE_MASK) != 0)
599 {
600 return (ecma_value_t) (uintptr_t) ecma_string_p;
601 }
602
603 return ecma_pointer_to_ecma_value (ecma_string_p) | ECMA_TYPE_STRING;
604 } /* ecma_make_string_value */
605
606 #if ENABLED (JERRY_ES2015)
607 /**
608 * Symbol value constructor
609 *
610 * @return ecma-value representation of the string argument
611 */
612 inline ecma_value_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_make_symbol_value(const ecma_string_t * ecma_symbol_p)613 ecma_make_symbol_value (const ecma_string_t *ecma_symbol_p) /**< symbol to reference in value */
614 {
615 JERRY_ASSERT (ecma_symbol_p != NULL);
616 JERRY_ASSERT (ecma_prop_name_is_symbol ((ecma_string_t *) ecma_symbol_p));
617
618 return ecma_pointer_to_ecma_value (ecma_symbol_p) | ECMA_TYPE_SYMBOL;
619 } /* ecma_make_symbol_value */
620 #endif /* ENABLED (JERRY_ES2015) */
621
622 /**
623 * Property-name value constructor
624 *
625 * @return ecma-value representation of a property name argument
626 */
627 inline ecma_value_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_make_prop_name_value(const ecma_string_t * ecma_prop_name_p)628 ecma_make_prop_name_value (const ecma_string_t *ecma_prop_name_p) /**< property name to reference in value */
629 {
630 JERRY_ASSERT (ecma_prop_name_p != NULL);
631
632 #if ENABLED (JERRY_ES2015)
633 if (ecma_prop_name_is_symbol ((ecma_string_t *) ecma_prop_name_p))
634 {
635 return ecma_make_symbol_value (ecma_prop_name_p);
636 }
637 #endif /* ENABLED (JERRY_ES2015) */
638
639 return ecma_make_string_value (ecma_prop_name_p);
640 } /* ecma_make_prop_name_value */
641
642 /**
643 * String value constructor
644 *
645 * @return ecma-value representation of the string argument
646 */
647 inline ecma_value_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_make_magic_string_value(lit_magic_string_id_t id)648 ecma_make_magic_string_value (lit_magic_string_id_t id) /**< magic string id */
649 {
650 return (ecma_value_t) ECMA_CREATE_DIRECT_STRING (ECMA_DIRECT_STRING_MAGIC, (uintptr_t) id);
651 } /* ecma_make_magic_string_value */
652
653 /**
654 * Object value constructor
655 *
656 * @return ecma-value representation of the object argument
657 */
658 inline ecma_value_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_make_object_value(const ecma_object_t * object_p)659 ecma_make_object_value (const ecma_object_t *object_p) /**< object to reference in value */
660 {
661 JERRY_ASSERT (object_p != NULL);
662
663 return ecma_pointer_to_ecma_value (object_p) | ECMA_TYPE_OBJECT;
664 } /* ecma_make_object_value */
665
666 /**
667 * Error reference constructor
668 *
669 * @return ecma-value representation of the Error reference
670 */
671 inline ecma_value_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_make_error_reference_value(const ecma_error_reference_t * error_ref_p)672 ecma_make_error_reference_value (const ecma_error_reference_t *error_ref_p) /**< error reference */
673 {
674 JERRY_ASSERT (error_ref_p != NULL);
675
676 return ecma_pointer_to_ecma_value (error_ref_p) | ECMA_TYPE_ERROR;
677 } /* ecma_make_error_reference_value */
678
679 /**
680 * Get integer value from an integer ecma value
681 *
682 * @return integer value
683 */
684 inline ecma_integer_value_t JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_get_integer_from_value(ecma_value_t value)685 ecma_get_integer_from_value (ecma_value_t value) /**< ecma value */
686 {
687 JERRY_ASSERT (ecma_is_value_integer_number (value));
688
689 return ((ecma_integer_value_t) value) >> ECMA_DIRECT_SHIFT;
690 } /* ecma_get_integer_from_value */
691
692 /**
693 * Get floating point value from an ecma value
694 *
695 * @return floating point value
696 */
697 inline ecma_number_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_get_float_from_value(ecma_value_t value)698 ecma_get_float_from_value (ecma_value_t value) /**< ecma value */
699 {
700 JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_FLOAT);
701
702 return *(ecma_number_t *) ecma_get_pointer_from_ecma_value (value);
703 } /* ecma_get_float_from_value */
704
705 /**
706 * Get floating point value pointer from an ecma value
707 *
708 * @return floating point value
709 */
710 inline ecma_number_t * JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_get_pointer_from_float_value(ecma_value_t value)711 ecma_get_pointer_from_float_value (ecma_value_t value) /**< ecma value */
712 {
713 JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_FLOAT);
714
715 return (ecma_number_t *) ecma_get_pointer_from_ecma_value (value);
716 } /* ecma_get_pointer_from_float_value */
717
718 /**
719 * Get floating point value from an ecma value
720 *
721 * @return floating point value
722 */
723 ecma_number_t JERRY_ATTR_PURE
ecma_get_number_from_value(ecma_value_t value)724 ecma_get_number_from_value (ecma_value_t value) /**< ecma value */
725 {
726 if (ecma_is_value_integer_number (value))
727 {
728 return (ecma_number_t) ecma_get_integer_from_value (value);
729 }
730
731 return ecma_get_float_from_value (value);
732 } /* ecma_get_number_from_value */
733
734 /**
735 * Get pointer to ecma-string from ecma value
736 *
737 * @return the string pointer
738 */
739 inline ecma_string_t *JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_get_string_from_value(ecma_value_t value)740 ecma_get_string_from_value (ecma_value_t value) /**< ecma value */
741 {
742 JERRY_ASSERT (ecma_is_value_string (value));
743
744 if ((value & ECMA_VALUE_TYPE_MASK) == ECMA_TYPE_DIRECT_STRING)
745 {
746 return (ecma_string_t *) (uintptr_t) value;
747 }
748
749 return (ecma_string_t *) ecma_get_pointer_from_ecma_value (value);
750 } /* ecma_get_string_from_value */
751
752 #if ENABLED (JERRY_ES2015)
753 /**
754 * Get pointer to ecma-string from ecma value
755 *
756 * @return the string pointer
757 */
758 inline ecma_string_t *JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_get_symbol_from_value(ecma_value_t value)759 ecma_get_symbol_from_value (ecma_value_t value) /**< ecma value */
760 {
761 JERRY_ASSERT (ecma_is_value_symbol (value));
762
763 return (ecma_string_t *) ecma_get_pointer_from_ecma_value (value);
764 } /* ecma_get_symbol_from_value */
765 #endif /* ENABLED (JERRY_ES2015) */
766
767 /**
768 * Get pointer to a property name from ecma value
769 *
770 * @return the string pointer
771 */
772 inline ecma_string_t *JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_get_prop_name_from_value(ecma_value_t value)773 ecma_get_prop_name_from_value (ecma_value_t value) /**< ecma value */
774 {
775 JERRY_ASSERT (ecma_is_value_prop_name (value));
776
777 if ((value & ECMA_VALUE_TYPE_MASK) == ECMA_TYPE_DIRECT_STRING)
778 {
779 return (ecma_string_t *) (uintptr_t) value;
780 }
781
782 return (ecma_string_t *) ecma_get_pointer_from_ecma_value (value);
783 } /* ecma_get_prop_name_from_value */
784
785 /**
786 * Get pointer to ecma-object from ecma value
787 *
788 * @return the pointer
789 */
790 inline ecma_object_t *JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_get_object_from_value(ecma_value_t value)791 ecma_get_object_from_value (ecma_value_t value) /**< ecma value */
792 {
793 JERRY_ASSERT (ecma_is_value_object (value));
794
795 return (ecma_object_t *) ecma_get_pointer_from_ecma_value (value);
796 } /* ecma_get_object_from_value */
797
798 /**
799 * Get pointer to error reference from ecma value
800 *
801 * @return the pointer
802 */
803 inline ecma_error_reference_t *JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_get_error_reference_from_value(ecma_value_t value)804 ecma_get_error_reference_from_value (ecma_value_t value) /**< ecma value */
805 {
806 JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_ERROR);
807
808 return (ecma_error_reference_t *) ecma_get_pointer_from_ecma_value (value);
809 } /* ecma_get_error_reference_from_value */
810
811 /**
812 * Invert a boolean value
813 *
814 * @return ecma value
815 */
816 inline ecma_value_t JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_invert_boolean_value(ecma_value_t value)817 ecma_invert_boolean_value (ecma_value_t value) /**< ecma value */
818 {
819 JERRY_ASSERT (ecma_is_value_boolean (value));
820
821 return (value ^ (1 << ECMA_DIRECT_SHIFT));
822 } /* ecma_invert_boolean_value */
823
824 /**
825 * Copy ecma value.
826 *
827 * @return copy of the given value
828 */
829 ecma_value_t
ecma_copy_value(ecma_value_t value)830 ecma_copy_value (ecma_value_t value) /**< value description */
831 {
832 switch (ecma_get_value_type_field (value))
833 {
834 case ECMA_TYPE_FLOAT:
835 {
836 ecma_number_t *num_p = (ecma_number_t *) ecma_get_pointer_from_ecma_value (value);
837
838 return ecma_create_float_number (*num_p);
839 }
840 case ECMA_TYPE_STRING:
841 {
842 ecma_ref_ecma_string (ecma_get_string_from_value (value));
843 return value;
844 }
845 #if ENABLED (JERRY_ES2015)
846 case ECMA_TYPE_SYMBOL:
847 {
848 ecma_ref_ecma_string (ecma_get_symbol_from_value (value));
849 return value;
850 }
851 #endif /* ENABLED (JERRY_ES2015) */
852 case ECMA_TYPE_OBJECT:
853 {
854 ecma_ref_object (ecma_get_object_from_value (value));
855 return value;
856 }
857 default:
858 {
859 JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT
860 || ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT_STRING);
861
862 return value;
863 }
864 }
865 } /* ecma_copy_value */
866
867 /**
868 * Copy ecma value.
869 *
870 * Note:
871 * this function is similar to ecma_copy_value, but it is
872 * faster for direct values since no function call is performed.
873 * It also increases the binary size so it is recommended for
874 * critical code paths only.
875 *
876 * @return copy of the given value
877 */
878 inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
ecma_fast_copy_value(ecma_value_t value)879 ecma_fast_copy_value (ecma_value_t value) /**< value description */
880 {
881 return (ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT) ? value : ecma_copy_value (value);
882 } /* ecma_fast_copy_value */
883
884 /**
885 * Copy the ecma value if not an object
886 *
887 * @return copy of the given value
888 */
889 inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
ecma_copy_value_if_not_object(ecma_value_t value)890 ecma_copy_value_if_not_object (ecma_value_t value) /**< value description */
891 {
892 if (!ecma_is_value_object (value))
893 {
894 return ecma_copy_value (value);
895 }
896
897 return value;
898 } /* ecma_copy_value_if_not_object */
899
900 /**
901 * Increase reference counter of a value if it is an object.
902 */
903 inline void JERRY_ATTR_ALWAYS_INLINE
ecma_ref_if_object(ecma_value_t value)904 ecma_ref_if_object (ecma_value_t value) /**< value description */
905 {
906 if (ecma_is_value_object (value))
907 {
908 ecma_ref_object (ecma_get_object_from_value (value));
909 }
910 } /* ecma_ref_if_object */
911
912 /**
913 * Decrease reference counter of a value if it is an object.
914 */
915 inline void JERRY_ATTR_ALWAYS_INLINE
ecma_deref_if_object(ecma_value_t value)916 ecma_deref_if_object (ecma_value_t value) /**< value description */
917 {
918 if (ecma_is_value_object (value))
919 {
920 ecma_deref_object (ecma_get_object_from_value (value));
921 }
922 } /* ecma_deref_if_object */
923
924 /**
925 * Assign a new value to an ecma-value
926 *
927 * Note:
928 * value previously stored in the property is freed
929 */
930 void
ecma_value_assign_value(ecma_value_t * value_p,ecma_value_t ecma_value)931 ecma_value_assign_value (ecma_value_t *value_p, /**< [in, out] ecma value */
932 ecma_value_t ecma_value) /**< value to assign */
933 {
934 JERRY_STATIC_ASSERT (ECMA_TYPE_DIRECT == 0,
935 ecma_type_direct_must_be_zero_for_the_next_check);
936
937 if (*value_p == ecma_value)
938 {
939 return;
940 }
941
942 if (ecma_get_value_type_field (ecma_value || *value_p) == ECMA_TYPE_DIRECT)
943 {
944 *value_p = ecma_value;
945 }
946 else if (ecma_is_value_float_number (ecma_value)
947 && ecma_is_value_float_number (*value_p))
948 {
949 const ecma_number_t *num_src_p = (ecma_number_t *) ecma_get_pointer_from_ecma_value (ecma_value);
950 ecma_number_t *num_dst_p = (ecma_number_t *) ecma_get_pointer_from_ecma_value (*value_p);
951
952 *num_dst_p = *num_src_p;
953 }
954 else
955 {
956 ecma_free_value_if_not_object (*value_p);
957 *value_p = ecma_copy_value_if_not_object (ecma_value);
958 }
959 } /* ecma_value_assign_value */
960
961 /**
962 * Update the value of a float number to a new value
963 *
964 * Note:
965 * The original value is destroyed.
966 *
967 * @return updated ecma value
968 */
969 ecma_value_t
ecma_update_float_number(ecma_value_t float_value,ecma_number_t new_number)970 ecma_update_float_number (ecma_value_t float_value, /**< original float value */
971 ecma_number_t new_number) /**< updated number value */
972 {
973 JERRY_ASSERT (ecma_is_value_float_number (float_value));
974
975 ecma_integer_value_t integer_number = (ecma_integer_value_t) new_number;
976 ecma_number_t *number_p = (ecma_number_t *) ecma_get_pointer_from_ecma_value (float_value);
977
978 if ((ecma_number_t) integer_number == new_number
979 && ((integer_number == 0) ? ecma_is_number_equal_to_positive_zero (new_number)
980 : ECMA_IS_INTEGER_NUMBER (integer_number)))
981 {
982 ecma_dealloc_number (number_p);
983 return ecma_make_integer_value (integer_number);
984 }
985
986 *number_p = new_number;
987 return float_value;
988 } /* ecma_update_float_number */
989
990 /**
991 * Assign a float number to an ecma-value
992 *
993 * Note:
994 * value previously stored in the property is freed
995 */
996 static void
ecma_value_assign_float_number(ecma_value_t * value_p,ecma_number_t ecma_number)997 ecma_value_assign_float_number (ecma_value_t *value_p, /**< [in, out] ecma value */
998 ecma_number_t ecma_number) /**< number to assign */
999 {
1000 if (ecma_is_value_float_number (*value_p))
1001 {
1002 ecma_number_t *num_dst_p = (ecma_number_t *) ecma_get_pointer_from_ecma_value (*value_p);
1003
1004 *num_dst_p = ecma_number;
1005 return;
1006 }
1007
1008 if (ecma_get_value_type_field (*value_p) != ECMA_TYPE_DIRECT
1009 && ecma_get_value_type_field (*value_p) != ECMA_TYPE_OBJECT)
1010 {
1011 ecma_free_value (*value_p);
1012 }
1013
1014 *value_p = ecma_create_float_number (ecma_number);
1015 } /* ecma_value_assign_float_number */
1016
1017 /**
1018 * Assign a number to an ecma-value
1019 *
1020 * Note:
1021 * value previously stored in the property is freed
1022 */
1023 void
ecma_value_assign_number(ecma_value_t * value_p,ecma_number_t ecma_number)1024 ecma_value_assign_number (ecma_value_t *value_p, /**< [in, out] ecma value */
1025 ecma_number_t ecma_number) /**< number to assign */
1026 {
1027 ecma_integer_value_t integer_value = (ecma_integer_value_t) ecma_number;
1028
1029 if ((ecma_number_t) integer_value == ecma_number
1030 && ((integer_value == 0) ? ecma_is_number_equal_to_positive_zero (ecma_number)
1031 : ECMA_IS_INTEGER_NUMBER (integer_value)))
1032 {
1033 if (ecma_get_value_type_field (*value_p) != ECMA_TYPE_DIRECT
1034 && ecma_get_value_type_field (*value_p) != ECMA_TYPE_OBJECT)
1035 {
1036 ecma_free_value (*value_p);
1037 }
1038 *value_p = ecma_make_integer_value (integer_value);
1039 return;
1040 }
1041
1042 ecma_value_assign_float_number (value_p, ecma_number);
1043 } /* ecma_value_assign_number */
1044
1045 /**
1046 * Free the ecma value
1047 */
1048 void
ecma_free_value(ecma_value_t value)1049 ecma_free_value (ecma_value_t value) /**< value description */
1050 {
1051 switch (ecma_get_value_type_field (value))
1052 {
1053 case ECMA_TYPE_FLOAT:
1054 {
1055 ecma_number_t *number_p = (ecma_number_t *) ecma_get_pointer_from_ecma_value (value);
1056 ecma_dealloc_number (number_p);
1057 break;
1058 }
1059
1060 case ECMA_TYPE_STRING:
1061 {
1062 ecma_string_t *string_p = ecma_get_string_from_value (value);
1063 ecma_deref_ecma_string (string_p);
1064 break;
1065 }
1066 #if ENABLED (JERRY_ES2015)
1067 case ECMA_TYPE_SYMBOL:
1068 {
1069 ecma_deref_ecma_string (ecma_get_symbol_from_value (value));
1070 break;
1071 }
1072 #endif /* ENABLED (JERRY_ES2015) */
1073 case ECMA_TYPE_OBJECT:
1074 {
1075 ecma_deref_object (ecma_get_object_from_value (value));
1076 break;
1077 }
1078
1079 default:
1080 {
1081 JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT
1082 || ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT_STRING);
1083
1084 /* no memory is allocated */
1085 break;
1086 }
1087 }
1088 } /* ecma_free_value */
1089
1090 /**
1091 * Free the ecma value
1092 *
1093 * Note:
1094 * this function is similar to ecma_free_value, but it is
1095 * faster for direct values since no function call is performed.
1096 * It also increases the binary size so it is recommended for
1097 * critical code paths only.
1098 */
1099 inline void JERRY_ATTR_ALWAYS_INLINE
ecma_fast_free_value(ecma_value_t value)1100 ecma_fast_free_value (ecma_value_t value) /**< value description */
1101 {
1102 if (ecma_get_value_type_field (value) != ECMA_TYPE_DIRECT)
1103 {
1104 ecma_free_value (value);
1105 }
1106 } /* ecma_fast_free_value */
1107
1108 /**
1109 * Free the ecma value if not an object
1110 */
1111 void
ecma_free_value_if_not_object(ecma_value_t value)1112 ecma_free_value_if_not_object (ecma_value_t value) /**< value description */
1113 {
1114 if (ecma_get_value_type_field (value) != ECMA_TYPE_OBJECT)
1115 {
1116 ecma_free_value (value);
1117 }
1118 } /* ecma_free_value_if_not_object */
1119
1120 /**
1121 * Free an ecma-value number
1122 */
1123 inline void JERRY_ATTR_ALWAYS_INLINE
ecma_free_number(ecma_value_t value)1124 ecma_free_number (ecma_value_t value) /**< value description */
1125 {
1126 JERRY_ASSERT (ecma_is_value_number (value));
1127
1128 if (ecma_is_value_float_number (value))
1129 {
1130 ecma_number_t *number_p = (ecma_number_t *) ecma_get_pointer_from_ecma_value (value);
1131 ecma_dealloc_number (number_p);
1132 }
1133 } /* ecma_free_number */
1134
1135 /**
1136 * Get the literal id associated with the given ecma_value type.
1137 * This operation is equivalent to the JavaScript 'typeof' operator.
1138 *
1139 * @returns one of the following value:
1140 * - LIT_MAGIC_STRING_UNDEFINED
1141 * - LIT_MAGIC_STRING_OBJECT
1142 * - LIT_MAGIC_STRING_BOOLEAN
1143 * - LIT_MAGIC_STRING_NUMBER
1144 * - LIT_MAGIC_STRING_STRING
1145 * - LIT_MAGIC_STRING_FUNCTION
1146 */
1147 lit_magic_string_id_t
ecma_get_typeof_lit_id(ecma_value_t value)1148 ecma_get_typeof_lit_id (ecma_value_t value) /**< input ecma value */
1149 {
1150 lit_magic_string_id_t ret_value = LIT_MAGIC_STRING__EMPTY;
1151
1152 if (ecma_is_value_undefined (value))
1153 {
1154 ret_value = LIT_MAGIC_STRING_UNDEFINED;
1155 }
1156 else if (ecma_is_value_null (value))
1157 {
1158 ret_value = LIT_MAGIC_STRING_OBJECT;
1159 }
1160 else if (ecma_is_value_boolean (value))
1161 {
1162 ret_value = LIT_MAGIC_STRING_BOOLEAN;
1163 }
1164 else if (ecma_is_value_number (value))
1165 {
1166 ret_value = LIT_MAGIC_STRING_NUMBER;
1167 }
1168 else if (ecma_is_value_string (value))
1169 {
1170 ret_value = LIT_MAGIC_STRING_STRING;
1171 }
1172 #if ENABLED (JERRY_ES2015)
1173 else if (ecma_is_value_symbol (value))
1174 {
1175 ret_value = LIT_MAGIC_STRING_SYMBOL;
1176 }
1177 #endif /* ENABLED (JERRY_ES2015) */
1178 else
1179 {
1180 JERRY_ASSERT (ecma_is_value_object (value));
1181
1182 ret_value = ecma_op_is_callable (value) ? LIT_MAGIC_STRING_FUNCTION : LIT_MAGIC_STRING_OBJECT;
1183 }
1184
1185 JERRY_ASSERT (ret_value != LIT_MAGIC_STRING__EMPTY);
1186
1187 return ret_value;
1188 } /* ecma_get_typeof_lit_id */
1189
1190 /**
1191 * @}
1192 * @}
1193 */
1194