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

Code before:
  ecma_value_t new_array = ecma_op_create_array_object (NULL, 0, false);
  JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
#endif /* ENABLED (JERRY_ES2015) */

  ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);

  /* 9. */
  uint32_t n = 0;

  if (ecma_op_object_is_fast_array (obj_p))
  {
    ecma_extended_object_t *ext_from_obj_p = (ecma_extended_object_t *) obj_p;

    if (ext_from_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE
        && len != 0
        && start < end)
    {
      uint32_t length = end - start;
      ecma_extended_object_t *ext_to_obj_p = (ecma_extended_object_t *) new_array_p;

      ecma_value_t *to_buffer_p;
      if (length == len)
      {
        to_buffer_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, new_array_p->u1.property_list_cp);
      }
      else
      {
        to_buffer_p = ecma_fast_array_extend (new_array_p, length);
      }
      ecma_value_t *from_buffer_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, obj_p->u1.property_list_cp);

      for (uint32_t k = start; k < end; k++, n++)
      {
#if ENABLED (JERRY_ES2015)
        ecma_free_value_if_not_object (to_buffer_p[n]);
#endif /* ENABLED (JERRY_ES2015) */
        to_buffer_p[n] = ecma_copy_value_if_not_object (from_buffer_p[k]);
      }

      ext_to_obj_p->u.array.u.hole_count -= length * ECMA_FAST_ARRAY_HOLE_ONE;

      return new_array;
    }
  }

  /* 10. */
  for (uint32_t k = start; k < end; k++, n++)
  {
    /* 10.c */
    ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, k);


Review comment (bug):
@dbatyai @LaszloLango I have updated the PR, but on this line we could have a nullpointer which will make a few tests fail. This patch will have to be rebased once #3480 lands, and then it should work.

Code after:
  }
  use_fast_path &= ecma_op_object_is_fast_array (ecma_get_object_from_value (new_array));
#else /* !ENABLED (JERRY_ES2015) */
  ecma_value_t new_array = ecma_op_create_array_object (NULL, 0, false);
  JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
#endif /* ENABLED (JERRY_ES2015) */

  ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);

  /* 9. */
  uint32_t n = 0;

  if (use_fast_path && copied_length > 0)
  {
    ecma_extended_object_t *ext_from_obj_p = (ecma_extended_object_t *) obj_p;

    if (ext_from_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE)
    {
      ecma_extended_object_t *ext_to_obj_p = (ecma_extended_object_t *) new_array_p;

#if ENABLED (JERRY_ES2015)
      uint32_t target_length = ext_to_obj_p->u.array.length;
      ecma_value_t *to_buffer_p;
      if (copied_length == target_length)
      {
        to_buffer_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, new_array_p->u1.property_list_cp);
      }
      else if (copied_length > target_length)
      {
        to_buffer_p = ecma_fast_array_extend (new_array_p, copied_length);
      }
      else
      {
        ecma_delete_fast_array_properties (new_array_p, copied_length);
        to_buffer_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, new_array_p->u1.property_list_cp);
      }
#else /* !ENABLED (JERRY_ES2015) */
      ecma_value_t *to_buffer_p = ecma_fast_array_extend (new_array_p, copied_length);
#endif /* ENABLED (JERRY_ES2015) */

      ecma_value_t *from_buffer_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, obj_p->u1.property_list_cp);

      for (uint32_t k = start; k < end; k++, n++)
      {
#if ENABLED (JERRY_ES2015)
        ecma_free_value_if_not_object (to_buffer_p[n]);
#endif /* ENABLED (JERRY_ES2015) */
        to_buffer_p[n] = ecma_copy_value_if_not_object (from_buffer_p[k]);
      }

      ext_to_obj_p->u.array.u.hole_count &= ECMA_FAST_ARRAY_HOLE_ONE - 1;