/** * Helper function for increase or decrease the remaining count. * * @return the current remaining count after increase or decrease. */ static ecma_length_t ecma_builtin_promise_remaining_inc_or_dec (ecma_value_t remaining, /**< the remaining count */ bool is_inc) /**< whether to increase the count */ { JERRY_ASSERT (ecma_is_value_object (remaining)); ecma_object_t *remaining_p = ecma_get_object_from_value (remaining); ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) remaining_p; JERRY_ASSERT (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_NUMBER_UL); JERRY_ASSERT (ecma_is_value_integer_number (ext_object_p->u.class_prop.u.value)); ecma_length_t current = (ecma_length_t) ecma_get_integer_from_value (ext_object_p->u.class_prop.u.value); if (is_inc) { current++; } else { current--; } ext_object_p->u.class_prop.u.value = ecma_make_uint32_value (current); return current; } /* ecma_builtin_promise_remaining_inc_or_dec */
/** * ToString operation. * * See also: * ECMA-262 v5, 9.8 * * @return ecma value * Returned value must be freed with ecma_free_value */ ecma_value_t ecma_op_to_string (ecma_value_t value) /**< ecma value */ { ecma_check_value_type_is_spec_defined (value); if (unlikely (ecma_is_value_object (value))) { ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); ECMA_TRY_CATCH (prim_value, ecma_op_to_primitive (value, ECMA_PREFERRED_TYPE_STRING), ret_value); ret_value = ecma_op_to_string (prim_value); ECMA_FINALIZE (prim_value); return ret_value; } else { ecma_string_t *res_p = NULL; if (ecma_is_value_string (value)) { res_p = ecma_get_string_from_value (value); res_p = ecma_copy_or_ref_ecma_string (res_p); } else if (ecma_is_value_integer_number (value)) { ecma_integer_value_t num = ecma_get_integer_from_value (value); if (num < 0) { res_p = ecma_new_ecma_string_from_number ((ecma_number_t) num); } else { res_p = ecma_new_ecma_string_from_uint32 ((uint32_t) num); } } else if (ecma_is_value_float_number (value)) { ecma_number_t num = ecma_get_float_from_value (value); res_p = ecma_new_ecma_string_from_number (num); } else if (ecma_is_value_undefined (value)) { res_p = ecma_get_magic_string (LIT_MAGIC_STRING_UNDEFINED); } else if (ecma_is_value_null (value)) { res_p = ecma_get_magic_string (LIT_MAGIC_STRING_NULL); } else { JERRY_ASSERT (ecma_is_value_boolean (value)); if (ecma_is_value_true (value)) { res_p = ecma_get_magic_string (LIT_MAGIC_STRING_TRUE); } else { res_p = ecma_get_magic_string (LIT_MAGIC_STRING_FALSE); } } return ecma_make_string_value (res_p); } } /* ecma_op_to_string */
/** * Runtime Semantics: PerformPromiseRace. * * See also: * ES2015 25.4.4.3.1 * * @return ecma value of the new promise. * Returned value must be freed with ecma_free_value. */ inline static ecma_value_t ecma_builtin_promise_do_race (ecma_value_t array, /**< the array for race */ ecma_value_t capability, /**< PromiseCapability record */ ecma_value_t ctor) /**< the caller of Promise.race */ { JERRY_ASSERT (ecma_is_value_object (capability) && ecma_is_value_object (array) && ecma_is_value_object (ctor)); JERRY_ASSERT (ecma_get_object_builtin_id (ecma_get_object_from_value (ctor)) == ECMA_BUILTIN_ID_PROMISE); JERRY_ASSERT (ecma_get_object_type (ecma_get_object_from_value (array)) == ECMA_OBJECT_TYPE_ARRAY); ecma_value_t ret = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); ecma_object_t *array_p = ecma_get_object_from_value (array); ecma_value_t len_value = ecma_op_object_get (array_p, magic_string_length_p); ecma_deref_ecma_string (magic_string_length_p); ecma_length_t len = (ecma_length_t) ecma_get_integer_from_value (len_value); ecma_fast_free_value (len_value); ecma_string_t *str_promise = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_PROMISE); ecma_string_t *str_resolve = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_RESOLVE); ecma_string_t *str_reject = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REJECT); ecma_value_t resolve = ecma_op_object_get (ecma_get_object_from_value (capability), str_resolve); ecma_value_t reject = ecma_op_object_get (ecma_get_object_from_value (capability), str_reject); for (ecma_length_t index = 0; index <= len; index++) { /* b-d. */ if (index == len) { ret = ecma_op_object_get (ecma_get_object_from_value (capability), str_promise); break; } /* e. */ ecma_string_t *str_index = ecma_new_ecma_string_from_uint32 (index); ecma_value_t array_item = ecma_op_object_get (array_p, str_index); ecma_deref_ecma_string (str_index); /* h. */ ecma_value_t next_promise = ecma_builtin_promise_resolve (ctor, array_item); ecma_free_value (array_item); /* i. */ if (ECMA_IS_VALUE_ERROR (next_promise)) { ret = next_promise; break; } /* j. */ ecma_value_t then_result = ecma_promise_then (next_promise, resolve, reject); ecma_free_value (next_promise); /* k. */ if (ECMA_IS_VALUE_ERROR (then_result)) { ret = then_result; break; } ecma_free_value (then_result); } ecma_free_value (reject); ecma_free_value (resolve); ecma_deref_ecma_string (str_promise); ecma_deref_ecma_string (str_resolve); ecma_deref_ecma_string (str_reject); JERRY_ASSERT (!ecma_is_value_empty (ret)); return ret; } /* ecma_builtin_promise_do_race */