DataViewConstructor.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /*
  2. * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibJS/Runtime/DataView.h>
  7. #include <LibJS/Runtime/DataViewConstructor.h>
  8. #include <LibJS/Runtime/Error.h>
  9. #include <LibJS/Runtime/GlobalObject.h>
  10. namespace JS {
  11. DataViewConstructor::DataViewConstructor(GlobalObject& global_object)
  12. : NativeFunction(vm().names.DataView, *global_object.function_prototype())
  13. {
  14. }
  15. void DataViewConstructor::initialize(GlobalObject& global_object)
  16. {
  17. auto& vm = this->vm();
  18. NativeFunction::initialize(global_object);
  19. // 25.3.3.1 DataView.prototype, https://tc39.es/ecma262/#sec-dataview.prototype
  20. define_property(vm.names.prototype, global_object.data_view_prototype(), 0);
  21. define_property(vm.names.length, Value(1), Attribute::Configurable);
  22. }
  23. DataViewConstructor::~DataViewConstructor()
  24. {
  25. }
  26. // 25.3.2.1 DataView ( buffer [ , byteOffset [ , byteLength ] ] ), https://tc39.es/ecma262/#sec-dataview-buffer-byteoffset-bytelength
  27. Value DataViewConstructor::call()
  28. {
  29. auto& vm = this->vm();
  30. vm.throw_exception<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, vm.names.DataView);
  31. return {};
  32. }
  33. // 25.3.2.1 DataView ( buffer [ , byteOffset [ , byteLength ] ] ), https://tc39.es/ecma262/#sec-dataview-buffer-byteoffset-bytelength
  34. Value DataViewConstructor::construct(Function&)
  35. {
  36. auto& vm = this->vm();
  37. auto buffer = vm.argument(0);
  38. if (!buffer.is_object() || !is<ArrayBuffer>(buffer.as_object())) {
  39. vm.throw_exception<TypeError>(global_object(), ErrorType::IsNotAn, buffer.to_string_without_side_effects(), vm.names.ArrayBuffer);
  40. return {};
  41. }
  42. auto& array_buffer = static_cast<ArrayBuffer&>(buffer.as_object());
  43. auto offset = vm.argument(1).to_index(global_object());
  44. if (vm.exception())
  45. return {};
  46. if (array_buffer.is_detached()) {
  47. vm.throw_exception<TypeError>(global_object(), ErrorType::DetachedArrayBuffer);
  48. return {};
  49. }
  50. auto buffer_byte_length = array_buffer.byte_length();
  51. if (offset > buffer_byte_length) {
  52. vm.throw_exception<RangeError>(global_object(), ErrorType::DataViewOutOfRangeByteOffset, offset, buffer_byte_length);
  53. return {};
  54. }
  55. size_t view_byte_length;
  56. if (vm.argument(2).is_undefined()) {
  57. view_byte_length = buffer_byte_length - offset;
  58. } else {
  59. view_byte_length = vm.argument(2).to_index(global_object());
  60. if (vm.exception())
  61. return {};
  62. if (offset + view_byte_length > buffer_byte_length) {
  63. vm.throw_exception<RangeError>(global_object(), ErrorType::InvalidLength, vm.names.DataView);
  64. return {};
  65. }
  66. }
  67. // FIXME: Use OrdinaryCreateFromConstructor(newTarget, "%DataView.prototype%")
  68. if (array_buffer.is_detached()) {
  69. vm.throw_exception<TypeError>(global_object(), ErrorType::DetachedArrayBuffer);
  70. return {};
  71. }
  72. return DataView::create(global_object(), &array_buffer, view_byte_length, offset);
  73. }
  74. }