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/**
17 * Implementation of ECMA-defined conversion routines
18 */
19
20#include <math.h>
21
22#include "ecma-alloc.h"
23#include "ecma-boolean-object.h"
24#include "ecma-conversion.h"
25#include "ecma-exceptions.h"
26#include "ecma-function-object.h"
27#include "ecma-gc.h"
28#include "ecma-globals.h"
29#include "ecma-helpers.h"
30#include "ecma-number-object.h"
31#include "ecma-objects.h"
32#include "ecma-objects-general.h"
33#include "ecma-string-object.h"
34#include "ecma-symbol-object.h"
35#include "ecma-try-catch-macro.h"
36#include "jrt-libc-includes.h"
37
38/** \addtogroup ecma ECMA
39 * @{
40 *
41 * \addtogroup ecmaconversion ECMA conversion routines
42 * @{
43 */
44
45/**
46 * CheckObjectCoercible operation.
47 *
48 * See also:
49 *          ECMA-262 v5, 9.10
50 *
51 * @return ecma value
52 *         Returned value must be freed with ecma_free_value
53 */
54ecma_value_t
55ecma_op_check_object_coercible (ecma_value_t value) /**< ecma value */
56{
57  ecma_check_value_type_is_spec_defined (value);
58
59  if (ecma_is_value_undefined (value)
60      || ecma_is_value_null (value))
61  {
62    return ecma_raise_type_error (ECMA_ERR_MSG ("Argument cannot be converted to an object."));
63  }
64  else
65  {
66    return ECMA_VALUE_EMPTY;
67  }
68} /* ecma_op_check_object_coercible */
69
70/**
71 * SameValue operation.
72 *
73 * See also:
74 *          ECMA-262 v5, 9.12
75 *
76 * @return true - if the value are same according to ECMA-defined SameValue algorithm,
77 *         false - otherwise
78 */
79bool
80ecma_op_same_value (ecma_value_t x, /**< ecma value */
81                    ecma_value_t y) /**< ecma value */
82{
83  if (x == y)
84  {
85    return true;
86  }
87
88  ecma_type_t type_of_x = ecma_get_value_type_field (x);
89
90  if (type_of_x != ecma_get_value_type_field (y)
91      || type_of_x == ECMA_TYPE_DIRECT)
92  {
93    return false;
94  }
95
96  if (ecma_is_value_number (x))
97  {
98    ecma_number_t x_num = ecma_get_number_from_value (x);
99    ecma_number_t y_num = ecma_get_number_from_value (y);
100
101    bool is_x_nan = ecma_number_is_nan (x_num);
102    bool is_y_nan = ecma_number_is_nan (y_num);
103
104    if (is_x_nan || is_y_nan)
105    {
106      return is_x_nan && is_y_nan;
107    }
108
109    if (ecma_number_is_zero (x_num)
110        && ecma_number_is_zero (y_num)
111        && ecma_number_is_negative (x_num) != ecma_number_is_negative (y_num))
112    {
113      return false;
114    }
115
116    return (x_num == y_num);
117  }
118
119  if (ecma_is_value_string (x))
120  {
121    ecma_string_t *x_str_p = ecma_get_string_from_value (x);
122    ecma_string_t *y_str_p = ecma_get_string_from_value (y);
123
124    return ecma_compare_ecma_strings (x_str_p, y_str_p);
125  }
126
127  JERRY_ASSERT (ecma_is_value_object (x) || ECMA_ASSERT_VALUE_IS_SYMBOL (x));
128
129  return false;
130} /* ecma_op_same_value */
131
132#if ENABLED (JERRY_ES2015_BUILTIN_MAP)
133/**
134 * SameValueZero operation.
135 *
136 * See also:
137 *          ECMA-262 v6, 7.2.10
138 *
139 * @return true - if the value are same according to ECMA-defined SameValueZero algorithm,
140 *         false - otherwise
141 */
142bool
143ecma_op_same_value_zero (ecma_value_t x, /**< ecma value */
144                         ecma_value_t y) /**< ecma value */
145{
146  if (ecma_is_value_number (x) && ecma_is_value_number (y))
147  {
148    ecma_number_t x_num = ecma_get_number_from_value (x);
149    ecma_number_t y_num = ecma_get_number_from_value (y);
150
151    bool is_x_nan = ecma_number_is_nan (x_num);
152    bool is_y_nan = ecma_number_is_nan (y_num);
153
154    if (is_x_nan || is_y_nan)
155    {
156      /*
157       * If both are NaN
158       *   return true;
159       * else
160       *   one of the numbers is NaN, and another - is not
161       *   return false;
162       */
163      return (is_x_nan && is_y_nan);
164    }
165
166    if (ecma_number_is_zero (x_num)
167        && ecma_number_is_zero (y_num)
168        && ecma_number_is_negative (x_num) != ecma_number_is_negative (y_num))
169    {
170      return true;
171    }
172
173    return (x_num == y_num);
174  }
175
176  return ecma_op_same_value (x, y);
177} /* ecma_op_same_value_zero */
178#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */
179
180/**
181 * ToPrimitive operation.
182 *
183 * See also:
184 *          ECMA-262 v5, 9.1
185 *
186 * @return ecma value
187 *         Returned value must be freed with ecma_free_value
188 */
189ecma_value_t
190ecma_op_to_primitive (ecma_value_t value, /**< ecma value */
191                      ecma_preferred_type_hint_t preferred_type) /**< preferred type hint */
192{
193  ecma_check_value_type_is_spec_defined (value);
194
195  if (ecma_is_value_object (value))
196  {
197    ecma_object_t *obj_p = ecma_get_object_from_value (value);
198
199    return ecma_op_object_default_value (obj_p, preferred_type);
200  }
201  else
202  {
203    return ecma_copy_value (value);
204  }
205} /* ecma_op_to_primitive */
206
207/**
208 * ToBoolean operation. Cannot throw an exception.
209 *
210 * See also:
211 *          ECMA-262 v5, 9.2
212 *
213 * @return true - if the logical value is true
214 *         false - otherwise
215 */
216bool
217ecma_op_to_boolean (ecma_value_t value) /**< ecma value */
218{
219  ecma_check_value_type_is_spec_defined (value);
220
221  if (ecma_is_value_simple (value))
222  {
223    JERRY_ASSERT (ecma_is_value_boolean (value)
224                  || ecma_is_value_undefined (value)
225                  || ecma_is_value_null (value));
226
227    return ecma_is_value_true (value);
228  }
229
230  if (ecma_is_value_integer_number (value))
231  {
232    return (value != ecma_make_integer_value (0));
233  }
234
235  if (ecma_is_value_float_number (value))
236  {
237    ecma_number_t num = ecma_get_float_from_value (value);
238
239    return (!ecma_number_is_nan (num) && !ecma_number_is_zero (num));
240  }
241
242  if (ecma_is_value_string (value))
243  {
244    ecma_string_t *str_p = ecma_get_string_from_value (value);
245
246    return !ecma_string_is_empty (str_p);
247  }
248
249  JERRY_ASSERT (ecma_is_value_object (value) || ECMA_ASSERT_VALUE_IS_SYMBOL (value));
250
251  return true;
252} /* ecma_op_to_boolean */
253
254/**
255 * ToNumber operation.
256 *
257 * See also:
258 *          ECMA-262 v5, 9.3
259 *
260 * @return ecma value
261 *         Returned value must be freed with ecma_free_value
262 */
263ecma_value_t
264ecma_op_to_number (ecma_value_t value) /**< ecma value */
265{
266  ecma_check_value_type_is_spec_defined (value);
267
268  if (ecma_is_value_integer_number (value))
269  {
270    return value;
271  }
272
273  if (ecma_is_value_float_number (value))
274  {
275    return ecma_copy_value (value);
276  }
277
278  if (ecma_is_value_string (value))
279  {
280    ecma_string_t *str_p = ecma_get_string_from_value (value);
281    return ecma_make_number_value (ecma_string_to_number (str_p));
282  }
283#if ENABLED (JERRY_ES2015)
284  if (ecma_is_value_symbol (value))
285  {
286    return ecma_raise_type_error (ECMA_ERR_MSG ("Cannot convert a Symbol value to a number."));
287  }
288#endif /* ENABLED (JERRY_ES2015) */
289
290  if (ecma_is_value_object (value))
291  {
292    ecma_value_t primitive_value = ecma_op_to_primitive (value, ECMA_PREFERRED_TYPE_NUMBER);
293
294    if (ECMA_IS_VALUE_ERROR (primitive_value))
295    {
296      return primitive_value;
297    }
298
299    ecma_value_t ret_value = ecma_op_to_number (primitive_value);
300    ecma_fast_free_value (primitive_value);
301    return ret_value;
302  }
303
304  if (ecma_is_value_undefined (value))
305  {
306    return ecma_make_nan_value ();
307  }
308
309  ecma_integer_value_t num = 0;
310
311  if (ecma_is_value_null (value))
312  {
313    num = 0;
314  }
315  else
316  {
317    JERRY_ASSERT (ecma_is_value_boolean (value));
318
319    num = ecma_is_value_true (value) ? 1 : 0;
320  }
321
322  return ecma_make_integer_value (num);
323} /* ecma_op_to_number */
324
325/**
326 * Helper to get the number contained in an ecma value.
327 *
328 * See also:
329 *          ECMA-262 v5, 9.3
330 *
331 * @return ECMA_VALUE_EMPTY if successful
332 *         conversion error otherwise
333 *         Returned value must be freed with ecma_free_value
334 */
335ecma_value_t
336ecma_get_number (ecma_value_t value, /**< ecma value*/
337                 ecma_number_t *number_p) /**< [out] ecma number */
338{
339  if (ecma_is_value_integer_number (value))
340  {
341    *number_p = ecma_get_integer_from_value (value);
342    return ECMA_VALUE_EMPTY;
343  }
344
345  if (ecma_is_value_float_number (value))
346  {
347    *number_p = ecma_get_float_from_value (value);
348    return ECMA_VALUE_EMPTY;
349  }
350
351  if (ecma_is_value_string (value))
352  {
353    ecma_string_t *str_p = ecma_get_string_from_value (value);
354    *number_p = ecma_string_to_number (str_p);
355    return ECMA_VALUE_EMPTY;
356  }
357
358  if (ecma_is_value_object (value))
359  {
360    ecma_value_t primitive_value = ecma_op_to_primitive (value, ECMA_PREFERRED_TYPE_NUMBER);
361
362    if (ECMA_IS_VALUE_ERROR (primitive_value))
363    {
364      return primitive_value;
365    }
366
367    ecma_value_t ret_value = ecma_get_number (primitive_value, number_p);
368    ecma_fast_free_value (primitive_value);
369    return ret_value;
370  }
371
372  if (ecma_is_value_undefined (value))
373  {
374    *number_p = ecma_number_make_nan ();
375    return ECMA_VALUE_EMPTY;
376  }
377
378  if (ecma_is_value_null (value))
379  {
380    *number_p = 0;
381    return ECMA_VALUE_EMPTY;
382  }
383
384#if ENABLED (JERRY_ES2015)
385  if (ecma_is_value_symbol (value))
386  {
387    return ecma_raise_type_error (ECMA_ERR_MSG ("Cannot convert a Symbol value to a number."));
388  }
389#endif /* ENABLED (JERRY_ES2015) */
390
391  JERRY_ASSERT (ecma_is_value_boolean (value));
392
393  *number_p = ecma_is_value_true (value) ? 1 : 0;
394  return ECMA_VALUE_EMPTY;
395} /* ecma_get_number */
396
397/**
398 * ToString operation.
399 *
400 * See also:
401 *          ECMA-262 v5, 9.8
402 *
403 * @return NULL - if the conversion fails
404 *         pointer to the string descriptor - otherwise
405 */
406ecma_string_t *
407ecma_op_to_string (ecma_value_t value) /**< ecma value */
408{
409  ecma_check_value_type_is_spec_defined (value);
410
411  if (JERRY_UNLIKELY (ecma_is_value_object (value)))
412  {
413    ecma_value_t prim_value = ecma_op_to_primitive (value, ECMA_PREFERRED_TYPE_STRING);
414
415    if (ECMA_IS_VALUE_ERROR (prim_value))
416    {
417      return NULL;
418    }
419
420    ecma_string_t *ret_string_p = ecma_op_to_string (prim_value);
421
422    ecma_free_value (prim_value);
423
424    return ret_string_p;
425  }
426
427  if (ecma_is_value_string (value))
428  {
429    ecma_string_t *res_p = ecma_get_string_from_value (value);
430    ecma_ref_ecma_string (res_p);
431    return res_p;
432  }
433  else if (ecma_is_value_integer_number (value))
434  {
435    ecma_integer_value_t num = ecma_get_integer_from_value (value);
436
437    if (num < 0)
438    {
439      return ecma_new_ecma_string_from_number ((ecma_number_t) num);
440    }
441    else
442    {
443      return ecma_new_ecma_string_from_uint32 ((uint32_t) num);
444    }
445  }
446  else if (ecma_is_value_float_number (value))
447  {
448    ecma_number_t num = ecma_get_float_from_value (value);
449    return ecma_new_ecma_string_from_number (num);
450  }
451  else if (ecma_is_value_undefined (value))
452  {
453    return ecma_get_magic_string (LIT_MAGIC_STRING_UNDEFINED);
454  }
455  else if (ecma_is_value_null (value))
456  {
457    return ecma_get_magic_string (LIT_MAGIC_STRING_NULL);
458  }
459#if ENABLED (JERRY_ES2015)
460  else if (ecma_is_value_symbol (value))
461  {
462    ecma_raise_type_error (ECMA_ERR_MSG ("Cannot convert a Symbol value to a string."));
463    return NULL;
464  }
465#endif /* ENABLED (JERRY_ES2015) */
466  JERRY_ASSERT (ecma_is_value_boolean (value));
467
468  if (ecma_is_value_true (value))
469  {
470    return ecma_get_magic_string (LIT_MAGIC_STRING_TRUE);
471  }
472
473  return ecma_get_magic_string (LIT_MAGIC_STRING_FALSE);
474} /* ecma_op_to_string */
475
476/**
477 * ToPropertyName operation.
478 *
479 * @return NULL - if the conversion fails
480 *         ecma-string - otherwise
481 */
482ecma_string_t *
483ecma_op_to_prop_name (ecma_value_t value) /**< ecma value */
484{
485  ecma_check_value_type_is_spec_defined (value);
486
487#if ENABLED (JERRY_ES2015)
488  if (ecma_is_value_symbol (value))
489  {
490    ecma_string_t *symbol_p = ecma_get_symbol_from_value (value);
491    ecma_ref_ecma_string (symbol_p);
492    return symbol_p;
493  }
494#endif /* ENABLED (JERRY_ES2015) */
495
496  return ecma_op_to_string (value);
497} /* ecma_op_to_prop_name */
498
499/**
500 * ToObject operation.
501 *
502 * See also:
503 *          ECMA-262 v5, 9.9
504 *
505 * @return ecma value
506 *         Returned value must be freed with ecma_free_value
507 */
508ecma_value_t
509ecma_op_to_object (ecma_value_t value) /**< ecma value */
510{
511  ecma_check_value_type_is_spec_defined (value);
512
513  if (ecma_is_value_number (value))
514  {
515    return ecma_op_create_number_object (value);
516  }
517  else if (ecma_is_value_string (value))
518  {
519    return ecma_op_create_string_object (&value, 1);
520  }
521  else if (ecma_is_value_object (value))
522  {
523    return ecma_copy_value (value);
524  }
525#if ENABLED (JERRY_ES2015)
526  else if (ecma_is_value_symbol (value))
527  {
528    return ecma_op_create_symbol_object (value);
529  }
530#endif /* ENABLED (JERRY_ES2015) */
531  else
532  {
533    if (ecma_is_value_undefined (value)
534        || ecma_is_value_null (value))
535    {
536      return ecma_raise_type_error (ECMA_ERR_MSG ("Argument cannot be converted to an object."));
537    }
538    else
539    {
540      JERRY_ASSERT (ecma_is_value_boolean (value));
541
542      return ecma_op_create_boolean_object (value);
543    }
544  }
545} /* ecma_op_to_object */
546
547/**
548 * FromPropertyDescriptor operation.
549 *
550 * See also:
551 *          ECMA-262 v5, 8.10.4
552 *
553 * @return constructed object
554 */
555ecma_object_t *
556ecma_op_from_property_descriptor (const ecma_property_descriptor_t *src_prop_desc_p) /**< property descriptor */
557{
558  /* 2. */
559  ecma_object_t *obj_p = ecma_op_create_object_object_noarg ();
560
561  ecma_value_t completion;
562  ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
563  {
564    prop_desc.flags = (ECMA_PROP_IS_VALUE_DEFINED
565                       | ECMA_PROP_IS_WRITABLE_DEFINED
566                       | ECMA_PROP_IS_WRITABLE
567                       | ECMA_PROP_IS_ENUMERABLE_DEFINED
568                       | ECMA_PROP_IS_ENUMERABLE
569                       | ECMA_PROP_IS_CONFIGURABLE_DEFINED
570                       | ECMA_PROP_IS_CONFIGURABLE);
571  }
572
573  /* 3. */
574  if (src_prop_desc_p->flags & (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED))
575  {
576    JERRY_ASSERT ((prop_desc.flags & (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED))
577                   == (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED));
578
579    /* a. */
580    prop_desc.value = src_prop_desc_p->value;
581
582    completion = ecma_op_object_define_own_property (obj_p,
583                                                     ecma_get_magic_string (LIT_MAGIC_STRING_VALUE),
584                                                     &prop_desc);
585    JERRY_ASSERT (ecma_is_value_true (completion));
586
587    /* b. */
588    prop_desc.value = ecma_make_boolean_value (src_prop_desc_p->flags & ECMA_PROP_IS_WRITABLE);
589
590    completion = ecma_op_object_define_own_property (obj_p,
591                                                     ecma_get_magic_string (LIT_MAGIC_STRING_WRITABLE),
592                                                     &prop_desc);
593    JERRY_ASSERT (ecma_is_value_true (completion));
594  }
595  else
596  {
597#if !ENABLED (JERRY_ES2015)
598    JERRY_ASSERT (src_prop_desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED));
599#else /* ENABLED (JERRY_ES2015) */
600    if (src_prop_desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED))
601#endif /* ENABLED (JERRY_ES2015) */
602    {
603      /* a. */
604      if (src_prop_desc_p->get_p == NULL)
605      {
606        prop_desc.value = ECMA_VALUE_UNDEFINED;
607      }
608      else
609      {
610        prop_desc.value = ecma_make_object_value (src_prop_desc_p->get_p);
611      }
612
613      completion = ecma_op_object_define_own_property (obj_p,
614                                                       ecma_get_magic_string (LIT_MAGIC_STRING_GET),
615                                                       &prop_desc);
616      JERRY_ASSERT (ecma_is_value_true (completion));
617
618      /* b. */
619      if (src_prop_desc_p->set_p == NULL)
620      {
621        prop_desc.value = ECMA_VALUE_UNDEFINED;
622      }
623      else
624      {
625        prop_desc.value = ecma_make_object_value (src_prop_desc_p->set_p);
626      }
627
628      completion = ecma_op_object_define_own_property (obj_p,
629                                                       ecma_get_magic_string (LIT_MAGIC_STRING_SET),
630                                                       &prop_desc);
631      JERRY_ASSERT (ecma_is_value_true (completion));
632    }
633  }
634
635  prop_desc.value = ecma_make_boolean_value (src_prop_desc_p->flags & ECMA_PROP_IS_ENUMERABLE);
636
637  completion = ecma_op_object_define_own_property (obj_p,
638                                                   ecma_get_magic_string (LIT_MAGIC_STRING_ENUMERABLE),
639                                                   &prop_desc);
640  JERRY_ASSERT (ecma_is_value_true (completion));
641
642  prop_desc.value = ecma_make_boolean_value (src_prop_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE);
643
644  completion = ecma_op_object_define_own_property (obj_p,
645                                                   ecma_get_magic_string (LIT_MAGIC_STRING_CONFIGURABLE),
646                                                   &prop_desc);
647  JERRY_ASSERT (ecma_is_value_true (completion));
648
649  return obj_p;
650} /* ecma_op_from_property_descriptor */
651
652/**
653 * ToPropertyDescriptor operation.
654 *
655 * See also:
656 *          ECMA-262 v5, 8.10.5
657 *
658 * @return ecma value
659 *         Returned value must be freed with ecma_free_value
660 */
661ecma_value_t
662ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */
663                                ecma_property_descriptor_t *out_prop_desc_p) /**< [out] filled property descriptor
664                                                                                  if return value is normal
665                                                                                  empty completion value */
666{
667  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
668
669  /* 1. */
670  if (!ecma_is_value_object (obj_value))
671  {
672    ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected an object."));
673  }
674  else
675  {
676    ecma_object_t *obj_p = ecma_get_object_from_value (obj_value);
677
678    /* 2. */
679    ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
680
681    /* 3. */
682    ECMA_TRY_CATCH (enumerable_prop_value,
683                    ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_ENUMERABLE)),
684                    ret_value);
685
686    if (ecma_is_value_found (enumerable_prop_value))
687    {
688      uint32_t is_enumerable = (ecma_op_to_boolean (enumerable_prop_value) ? ECMA_PROP_IS_ENUMERABLE
689                                                                           : ECMA_PROP_NO_OPTS);
690
691      prop_desc.flags |= (uint16_t) (ECMA_PROP_IS_ENUMERABLE_DEFINED | is_enumerable);
692    }
693
694    ECMA_FINALIZE (enumerable_prop_value);
695
696    if (!ECMA_IS_VALUE_ERROR (ret_value))
697    {
698      JERRY_ASSERT (ecma_is_value_empty (ret_value));
699
700      /* 4. */
701      ECMA_TRY_CATCH (configurable_prop_value,
702                      ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_CONFIGURABLE)),
703                      ret_value);
704
705      if (ecma_is_value_found (configurable_prop_value))
706      {
707        uint32_t is_configurable = (ecma_op_to_boolean (configurable_prop_value) ? ECMA_PROP_IS_CONFIGURABLE
708                                                                                 : ECMA_PROP_NO_OPTS);
709
710        prop_desc.flags |= (uint16_t) (ECMA_PROP_IS_CONFIGURABLE_DEFINED | is_configurable);
711      }
712
713      ECMA_FINALIZE (configurable_prop_value);
714    }
715
716    if (!ECMA_IS_VALUE_ERROR (ret_value))
717    {
718      JERRY_ASSERT (ecma_is_value_empty (ret_value));
719
720      /* 5. */
721      ECMA_TRY_CATCH (value_prop_value,
722                      ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_VALUE)),
723                      ret_value);
724
725      if (ecma_is_value_found (value_prop_value))
726      {
727        prop_desc.flags |= ECMA_PROP_IS_VALUE_DEFINED;
728        prop_desc.value = ecma_copy_value (value_prop_value);
729      }
730
731      ECMA_FINALIZE (value_prop_value);
732    }
733
734    if (!ECMA_IS_VALUE_ERROR (ret_value))
735    {
736      JERRY_ASSERT (ecma_is_value_empty (ret_value));
737
738      /* 6. */
739      ECMA_TRY_CATCH (writable_prop_value,
740                      ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_WRITABLE)),
741                      ret_value);
742
743      if (ecma_is_value_found (writable_prop_value))
744      {
745        uint32_t is_writable = (ecma_op_to_boolean (writable_prop_value) ? ECMA_PROP_IS_WRITABLE
746                                                                         : ECMA_PROP_NO_OPTS);
747
748        prop_desc.flags |= (uint16_t) (ECMA_PROP_IS_WRITABLE_DEFINED | is_writable);
749      }
750
751      ECMA_FINALIZE (writable_prop_value);
752    }
753
754    if (!ECMA_IS_VALUE_ERROR (ret_value))
755    {
756      JERRY_ASSERT (ecma_is_value_empty (ret_value));
757
758      /* 7. */
759      ECMA_TRY_CATCH (get_prop_value,
760                      ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_GET)),
761                      ret_value);
762
763      if (ecma_is_value_found (get_prop_value))
764      {
765        if (!ecma_op_is_callable (get_prop_value)
766            && !ecma_is_value_undefined (get_prop_value))
767        {
768          ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected a function."));
769        }
770        else
771        {
772          prop_desc.flags |= ECMA_PROP_IS_GET_DEFINED;
773
774          if (ecma_is_value_undefined (get_prop_value))
775          {
776            prop_desc.get_p = NULL;
777          }
778          else
779          {
780            JERRY_ASSERT (ecma_is_value_object (get_prop_value));
781
782            ecma_object_t *get_p = ecma_get_object_from_value (get_prop_value);
783            ecma_ref_object (get_p);
784
785            prop_desc.get_p = get_p;
786          }
787        }
788      }
789
790      ECMA_FINALIZE (get_prop_value);
791    }
792
793    if (!ECMA_IS_VALUE_ERROR (ret_value))
794    {
795      JERRY_ASSERT (ecma_is_value_empty (ret_value));
796
797      /* 8. */
798      ECMA_TRY_CATCH (set_prop_value,
799                      ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_SET)),
800                      ret_value);
801
802      if (ecma_is_value_found (set_prop_value))
803      {
804        if (!ecma_op_is_callable (set_prop_value)
805            && !ecma_is_value_undefined (set_prop_value))
806        {
807          ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected a function."));
808        }
809        else
810        {
811          prop_desc.flags |= ECMA_PROP_IS_SET_DEFINED;
812
813          if (ecma_is_value_undefined (set_prop_value))
814          {
815            prop_desc.set_p = NULL;
816          }
817          else
818          {
819            JERRY_ASSERT (ecma_is_value_object (set_prop_value));
820
821            ecma_object_t *set_p = ecma_get_object_from_value (set_prop_value);
822            ecma_ref_object (set_p);
823
824            prop_desc.set_p = set_p;
825          }
826        }
827      }
828
829      ECMA_FINALIZE (set_prop_value);
830    }
831
832    if (!ECMA_IS_VALUE_ERROR (ret_value))
833    {
834      JERRY_ASSERT (ecma_is_value_empty (ret_value));
835
836      /* 9. */
837      if ((prop_desc.flags & (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED))
838           && (prop_desc.flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)))
839      {
840        ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Accessors cannot be writable."));
841      }
842    }
843
844    if (!ECMA_IS_VALUE_ERROR (ret_value))
845    {
846      JERRY_ASSERT (ecma_is_value_empty (ret_value));
847    }
848    else
849    {
850      ecma_free_property_descriptor (&prop_desc);
851    }
852
853    *out_prop_desc_p = prop_desc;
854  }
855
856  return ret_value;
857} /* ecma_op_to_property_descriptor */
858
859/**
860 * ToInteger operation.
861 *
862 * See also:
863 *          ECMA-262 v5, 9.4
864 *          ECMA-262 v6, 7.1.4
865 *
866 * @return ECMA_VALUE_EMPTY if successful
867 *         conversion error otherwise
868 */
869ecma_value_t
870ecma_op_to_integer (ecma_value_t value, /**< ecma value */
871                    ecma_number_t *number_p) /**< [out] ecma number */
872{
873  if (ECMA_IS_VALUE_ERROR (value))
874  {
875    return value;
876  }
877
878  /* 1 */
879  ecma_value_t to_number = ecma_get_number (value, number_p);
880
881  /* 2 */
882  if (ECMA_IS_VALUE_ERROR (to_number))
883  {
884    return to_number;
885  }
886
887  ecma_number_t number = *number_p;
888
889  /* 3 */
890  if (ecma_number_is_nan (number))
891  {
892    *number_p = ECMA_NUMBER_ZERO;
893    return ECMA_VALUE_EMPTY;
894  }
895
896  /* 4 */
897  if (ecma_number_is_zero (number) || ecma_number_is_infinity (number))
898  {
899    return ECMA_VALUE_EMPTY;
900  }
901
902  ecma_number_t floor_fabs = floor (fabs (number));
903
904  /* 5 */
905  *number_p = ecma_number_is_negative (number) ? -floor_fabs : floor_fabs;
906  return ECMA_VALUE_EMPTY;
907} /* ecma_op_to_integer */
908
909/**
910 * ToLength operation.
911 *
912 * See also:
913 *          ECMA-262 v6, 7.1.15
914 *
915 * @return ECMA_VALUE_EMPTY if successful
916 *         conversion error otherwise
917 */
918ecma_value_t
919ecma_op_to_length (ecma_value_t value, /**< ecma value */
920                   uint32_t *length) /**< [out] ecma number */
921{
922  /* 1 */
923  if (ECMA_IS_VALUE_ERROR (value))
924  {
925    return value;
926  }
927
928#if ENABLED (JERRY_ES2015)
929  /* 2 */
930  ecma_number_t num;
931  ecma_value_t length_num = ecma_op_to_integer (value, &num);
932
933  /* 3 */
934  if (ECMA_IS_VALUE_ERROR (length_num))
935  {
936    return length_num;
937  }
938
939  /* 4 */
940  if (num <= 0.0f)
941  {
942    *length = 0;
943    return ECMA_VALUE_EMPTY;
944  }
945
946  /* 5 */
947  if (num >= (ecma_number_t) UINT32_MAX)
948  {
949    *length = UINT32_MAX;
950    return ECMA_VALUE_EMPTY;
951  }
952
953  /* 6 */
954  *length = (uint32_t) num;
955  return ECMA_VALUE_EMPTY;
956#else /* !ENABLED (JERRY_ES2015) */
957  /* In the case of ES5, ToLength(ES6) operation is the same as ToUint32(ES5) */
958  ecma_number_t num;
959  ecma_value_t to_number = ecma_get_number (value, &num);
960
961  /* 2 */
962  if (ECMA_IS_VALUE_ERROR (to_number))
963  {
964    return to_number;
965  }
966
967  *length = ecma_number_to_uint32 (num);
968  return ECMA_VALUE_EMPTY;
969#endif /* ENABLED (JERRY_ES2015) */
970} /* ecma_op_to_length */
971
972#if ENABLED (JERRY_ES2015)
973/**
974 * CreateListFromArrayLike operation.
975 * Different types are not handled yet.
976 *
977 * See also:
978 *          ECMA-262 v6, 7.3.17
979 *
980 * @return ecma_collection_t if successful
981 *         NULL otherwise
982 */
983ecma_collection_t *
984ecma_op_create_list_from_array_like (ecma_value_t arr,  /**< array value */
985                                     bool prop_names_only) /**< true - accept only property names
986                                                                false - otherwise */
987{
988  /* 1. */
989  JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (arr));
990
991  /* 3. */
992  if (!ecma_is_value_object (arr))
993  {
994    ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an Object."));
995    return NULL;
996  }
997  ecma_object_t *obj_p = ecma_get_object_from_value (arr);
998
999  /* 4. 5. */
1000  ecma_length_t len;
1001  if (ECMA_IS_VALUE_ERROR (ecma_op_object_get_length (obj_p, &len)))
1002  {
1003    return NULL;
1004  }
1005
1006  /* 6. */
1007  ecma_collection_t *list_ptr = ecma_new_collection ();
1008
1009  /* 7. 8. */
1010  for (uint32_t idx = 0; idx < len; idx++)
1011  {
1012    ecma_value_t next = ecma_op_object_get_by_uint32_index (obj_p, idx);
1013    if (ECMA_IS_VALUE_ERROR (next))
1014    {
1015      ecma_collection_free (list_ptr);
1016      return NULL;
1017    }
1018
1019    if (prop_names_only
1020        && !ecma_is_value_prop_name (next))
1021    {
1022      ecma_free_value (next);
1023      ecma_collection_free (list_ptr);
1024      ecma_raise_type_error (ECMA_ERR_MSG ("Property name is neither Symbol nor String."));
1025      return NULL;
1026    }
1027
1028    ecma_collection_push_back (list_ptr, next);
1029  }
1030
1031  /* 9. */
1032  return list_ptr;
1033} /* ecma_op_create_list_from_array_like */
1034#endif /* ENABLED (JERRY_ES2015) */
1035
1036/**
1037 * @}
1038 * @}
1039 */
1040