Repository: jerryscript-project/jerryscript
File: jerry-core/api/jerry.c (C)

Code before:
  if (!ecma_is_value_object (value))
  {
    return false;
  }

  ecma_object_t *obj_p = ecma_get_object_from_value (value);
  ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
  ecma_object_type_t type = ecma_get_object_type (obj_p);

  if (jerry_get_container_type (value) == JERRY_CONTAINER_TYPE_INVALID &&
        !(type == ECMA_OBJECT_TYPE_CLASS &&
          (ext_obj_p->u.cls.type == ECMA_OBJECT_CLASS_MAP_ITERATOR ||
           ext_obj_p->u.cls.type == ECMA_OBJECT_CLASS_SET_ITERATOR)))
  {
    ecma_collection_free (collection_buffer);
    return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Value is not a Container or Iterator")));
  }

  ecma_collection_t *container_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, ext_obj_p->u.cls.u3.value);
  lit_magic_string_id_t lit_id = ext_obj_p->u.cls.u2.container_id;
  uint32_t entry_count =  ECMA_CONTAINER_ENTRY_COUNT (container_p);
  uint8_t entry_size = ecma_op_container_entry_size (lit_id);

  uint32_t index = 0;
  uint8_t iterator_kind = ECMA_ITERATOR__COUNT;
  ecma_value_t *start_p = ECMA_CONTAINER_START (container_p);
  bool is_value_iterator = false;

  *is_key_value_p = false;

  if (type == ECMA_OBJECT_TYPE_CLASS &&
      (ext_obj_p->u.cls.type == ECMA_OBJECT_CLASS_MAP_ITERATOR ||
        ext_obj_p->u.cls.type == ECMA_OBJECT_CLASS_SET_ITERATOR))
  {
    is_value_iterator = true;

    ecma_value_t iterated_value = ext_obj_p->u.cls.u3.iterated_value;

    if (ecma_is_value_empty (iterated_value))
    {
      return ecma_op_new_array_object_from_collection (collection_buffer, false);
    }

    ecma_extended_object_t *map_object_p = (ecma_extended_object_t *) (ecma_get_object_from_value (iterated_value));
    lit_id = map_object_p->u.cls.u2.container_id;

    container_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, map_object_p->u.cls.u3.value);
    entry_count = ECMA_CONTAINER_ENTRY_COUNT (container_p);
    index = ext_obj_p->u.cls.u2.iterator_index;

    if (index == entry_count)

Review comment (suggestion):
If the input is a Map/Set iterator these are "calculated" twice. It would be better if we calculate these once for each type. Maybe we could add an else block for the `if` bellow where these values are assigned. 

Code after:
} /* jerry_create_container */

/**
 * Get the type of the given container object.
 *
 * @return Corresponding type to the given container object.
 */
jerry_container_type_t
jerry_get_container_type (const jerry_value_t value) /**< the container object */
{
  jerry_assert_api_available ();

#if JERRY_BUILTIN_CONTAINER
  if (ecma_is_value_object (value))
  {
    ecma_object_t *obj_p = ecma_get_object_from_value (value);

    if (ecma_object_class_is (obj_p, ECMA_OBJECT_CLASS_CONTAINER))
    {
      switch (((ecma_extended_object_t *) obj_p)->u.cls.u2.container_id)
      {
#if JERRY_BUILTIN_MAP
        case LIT_MAGIC_STRING_MAP_UL:
        {
          return JERRY_CONTAINER_TYPE_MAP;
        }
#endif /* JERRY_BUILTIN_MAP */
#if JERRY_BUILTIN_SET
        case LIT_MAGIC_STRING_SET_UL:
        {
          return JERRY_CONTAINER_TYPE_SET;
        }
#endif /* JERRY_BUILTIN_SET */
#if JERRY_BUILTIN_WEAKMAP
        case LIT_MAGIC_STRING_WEAKMAP_UL:
        {
          return JERRY_CONTAINER_TYPE_WEAKMAP;
        }
#endif /* JERRY_BUILTIN_WEAKMAP */
#if JERRY_BUILTIN_WEAKSET
        case LIT_MAGIC_STRING_WEAKSET_UL:
        {
          return JERRY_CONTAINER_TYPE_WEAKSET;
        }
#endif /* JERRY_BUILTIN_WEAKSET */
        default:
        {
          return JERRY_CONTAINER_TYPE_INVALID;
        }
      }
    }