Repository: jerryscript-project/jerryscript
File: jerry-core/ecma/operations/ecma-dataview-object.c (C)

Code before:
    view_byte_length = (uint32_t) byte_length_to_index;
  }
  else
  {
    /* 7.a */
    view_byte_length = (uint32_t) (buffer_byte_length - offset);
  }

  /* 9. */
  ecma_object_t *prototype_obj_p = ecma_op_get_prototype_from_constructor (JERRY_CONTEXT (current_new_target),
                                                                           ECMA_BUILTIN_ID_DATAVIEW_PROTOTYPE);
  if (JERRY_UNLIKELY (prototype_obj_p == NULL))
  {
    return ECMA_VALUE_ERROR;
  }

  ecma_object_t *object_p = ecma_create_object (prototype_obj_p,
                                                sizeof (ecma_dataview_object_t),
                                                ECMA_OBJECT_TYPE_CLASS);

  ecma_deref_object (prototype_obj_p);

  /* 10. */
  if (ecma_arraybuffer_is_detached (buffer_p))
  {
    ecma_deref_object (object_p);
    return ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer has been detached."));
  }

  /* 11 - 14. */
  ecma_dataview_object_t *dataview_obj_p = (ecma_dataview_object_t *) object_p;
  dataview_obj_p->header.u.class_prop.class_id = LIT_MAGIC_STRING_DATAVIEW_UL;
  dataview_obj_p->header.u.class_prop.u.length = view_byte_length;
  dataview_obj_p->buffer_p = buffer_p;
  dataview_obj_p->byte_offset = (uint32_t) offset;

  return ecma_make_object_value (object_p);
} /* ecma_op_dataview_create */

/**
 * Get the DataView object pointer
 *
 * Note:
 *   If the function returns with NULL, the error object has
 *   already set, and the caller must return with ECMA_VALUE_ERROR
 *
 * @return pointer to the dataView if this_arg is a valid dataView object
 *         NULL otherwise
 */
ecma_dataview_object_t *
ecma_op_dataview_get_object (ecma_value_t this_arg) /**< this argument */

Review comment (bug):
Wait for a second. This leads to undefined behavior in GC. Since the allocated object's type is `ECMA_OBJECT_TYPE_CLASS` the mark & sweep depends on it's internal `class_id` which is uninitialized at this point. So perform the deatched arraybuffer check **after** then the dataview object has been fully initialized.

Code after:
    view_byte_length = (uint32_t) byte_length_to_index;
  }
  else
  {
    /* 7.a */
    view_byte_length = (uint32_t) (buffer_byte_length - offset);
  }

  /* 9. */
  ecma_object_t *prototype_obj_p = ecma_op_get_prototype_from_constructor (JERRY_CONTEXT (current_new_target),
                                                                           ECMA_BUILTIN_ID_DATAVIEW_PROTOTYPE);
  if (JERRY_UNLIKELY (prototype_obj_p == NULL))
  {
    return ECMA_VALUE_ERROR;
  }

  /* 10. */
  if (ecma_arraybuffer_is_detached (buffer_p))
  {
    ecma_deref_object (prototype_obj_p);
    return ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer has been detached."));
  }

  /* 9. */
  /* It must happen after 10., because uninitialized object can't be destroyed properly. */
  ecma_object_t *object_p = ecma_create_object (prototype_obj_p,
                                                sizeof (ecma_dataview_object_t),
                                                ECMA_OBJECT_TYPE_CLASS);

  ecma_deref_object (prototype_obj_p);

  /* 11 - 14. */
  ecma_dataview_object_t *dataview_obj_p = (ecma_dataview_object_t *) object_p;
  dataview_obj_p->header.u.class_prop.class_id = LIT_MAGIC_STRING_DATAVIEW_UL;
  dataview_obj_p->header.u.class_prop.u.length = view_byte_length;
  dataview_obj_p->buffer_p = buffer_p;
  dataview_obj_p->byte_offset = (uint32_t) offset;

  return ecma_make_object_value (object_p);
} /* ecma_op_dataview_create */

/**
 * Get the DataView object pointer
 *
 * Note:
 *   If the function returns with NULL, the error object has
 *   already set, and the caller must return with ECMA_VALUE_ERROR
 *
 * @return pointer to the dataView if this_arg is a valid dataView object
 *         NULL otherwise
 */