Repository: jerryscript-project/jerryscript
File: jerry-core/ecma/builtin-objects/ecma-builtin-promise.c (C)

Code before:
ecma_builtin_promise_helper (ecma_value_t this_arg, /**< 'this' argument */
                             ecma_value_t iterable, /**< the items to be resolved */
                             uint8_t builtin_routine_id) /**< built-in wide routine identifier */
{
  ecma_object_t *capability_obj_p = ecma_promise_new_capability (this_arg, ECMA_VALUE_UNDEFINED);

  if (JERRY_UNLIKELY (capability_obj_p == NULL))
  {
    return ECMA_VALUE_ERROR;
  }

  ecma_value_t resolve = ecma_op_object_get_by_magic_id (ecma_get_object_from_value (this_arg),
                                                         LIT_MAGIC_STRING_RESOLVE);

  if (ECMA_IS_VALUE_ERROR (resolve))
  {
    resolve = ecma_builtin_promise_reject_abrupt (resolve, capability_obj_p);
    ecma_deref_object (capability_obj_p);
    return resolve;
  }

  if (!ecma_op_is_callable (resolve))
  {
    ecma_free_value (resolve);
    ecma_raise_type_error (ECMA_ERR_MSG ("Resolve method must be callable"));
    resolve = ecma_builtin_promise_reject_abrupt (ECMA_VALUE_ERROR, capability_obj_p);
    ecma_deref_object (capability_obj_p);
    return resolve;
  }

  ecma_value_t next_method;
  ecma_value_t iterator = ecma_op_get_iterator (iterable, ECMA_VALUE_SYNC_ITERATOR, &next_method);
  iterator = ecma_builtin_promise_reject_abrupt (iterator, capability_obj_p);

  if (ECMA_IS_VALUE_ERROR (iterator))
  {
    ecma_deref_object (capability_obj_p);
    return iterator;
  }

  ecma_value_t ret = ECMA_VALUE_EMPTY;
  bool is_done = false;
  if (builtin_routine_id == ECMA_PROMISE_ROUTINE_RACE)
  {
    ret = ecma_builtin_promise_perform_race (iterator, next_method, capability_obj_p, this_arg, resolve, &is_done);
  }
  else
  {
    ret = ecma_builtin_promise_perform_all_or_all_settled (iterator, next_method, capability_obj_p, this_arg, resolve,
                                                           builtin_routine_id, &is_done);
  }

Review comment (suggestion):
in

```
if (ECMA_IS_VALUE_ERROR (iterator))
  {
    ecma_deref_object (capability_obj_p);
    return iterator;
  }
```
above, there is a missing `resolve` release

Code after:
static ecma_value_t
ecma_builtin_promise_helper (ecma_value_t this_arg, /**< 'this' argument */
                             ecma_value_t iterable, /**< the items to be resolved */
                             uint8_t builtin_routine_id) /**< built-in wide routine
                                                          *   identifier */
{
  ecma_object_t *capability_obj_p = ecma_promise_new_capability (this_arg, ECMA_VALUE_UNDEFINED);

  if (JERRY_UNLIKELY (capability_obj_p == NULL))
  {
    return ECMA_VALUE_ERROR;
  }

  ecma_value_t resolve = ecma_op_object_get_by_magic_id (ecma_get_object_from_value (this_arg),
                                                         LIT_MAGIC_STRING_RESOLVE);

  if (ECMA_IS_VALUE_ERROR (resolve))
  {
    resolve = ecma_builtin_promise_reject_abrupt (resolve, capability_obj_p);
    ecma_deref_object (capability_obj_p);
    return resolve;
  }

  if (!ecma_op_is_callable (resolve))
  {
    ecma_free_value (resolve);
    ecma_raise_type_error (ECMA_ERR_MSG ("Resolve method must be callable"));
    resolve = ecma_builtin_promise_reject_abrupt (ECMA_VALUE_ERROR, capability_obj_p);
    ecma_deref_object (capability_obj_p);
    return resolve;
  }

  ecma_value_t next_method;
  ecma_value_t iterator = ecma_op_get_iterator (iterable, ECMA_VALUE_SYNC_ITERATOR, &next_method);
  iterator = ecma_builtin_promise_reject_abrupt (iterator, capability_obj_p);

  if (ECMA_IS_VALUE_ERROR (iterator))
  {
    ecma_deref_object (capability_obj_p);
    return iterator;
  }

  ecma_value_t ret = ECMA_VALUE_EMPTY;
  bool is_done = false;

  if (builtin_routine_id == ECMA_PROMISE_ROUTINE_RACE)
  {
    ret = ecma_builtin_promise_perform_race (iterator, next_method, capability_obj_p, this_arg, resolve, &is_done);
  }
  else
  {