• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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