ArrayBuffer.cpp 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /*
  2. * Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibJS/Runtime/AbstractOperations.h>
  7. #include <LibJS/Runtime/ArrayBuffer.h>
  8. #include <LibJS/Runtime/GlobalObject.h>
  9. namespace JS {
  10. ThrowCompletionOr<ArrayBuffer*> ArrayBuffer::create(GlobalObject& global_object, size_t byte_length)
  11. {
  12. auto buffer = ByteBuffer::create_zeroed(byte_length);
  13. if (buffer.is_error())
  14. return global_object.vm().throw_completion<RangeError>(global_object, ErrorType::NotEnoughMemoryToAllocate, byte_length);
  15. return global_object.heap().allocate<ArrayBuffer>(global_object, buffer.release_value(), *global_object.array_buffer_prototype());
  16. }
  17. ArrayBuffer* ArrayBuffer::create(GlobalObject& global_object, ByteBuffer buffer)
  18. {
  19. return global_object.heap().allocate<ArrayBuffer>(global_object, move(buffer), *global_object.array_buffer_prototype());
  20. }
  21. ArrayBuffer* ArrayBuffer::create(GlobalObject& global_object, ByteBuffer* buffer)
  22. {
  23. return global_object.heap().allocate<ArrayBuffer>(global_object, buffer, *global_object.array_buffer_prototype());
  24. }
  25. ArrayBuffer::ArrayBuffer(ByteBuffer buffer, Object& prototype)
  26. : Object(prototype)
  27. , m_buffer(move(buffer))
  28. , m_detach_key(js_undefined())
  29. {
  30. }
  31. ArrayBuffer::ArrayBuffer(ByteBuffer* buffer, Object& prototype)
  32. : Object(prototype)
  33. , m_buffer(buffer)
  34. , m_detach_key(js_undefined())
  35. {
  36. }
  37. ArrayBuffer::~ArrayBuffer()
  38. {
  39. }
  40. void ArrayBuffer::visit_edges(Cell::Visitor& visitor)
  41. {
  42. Base::visit_edges(visitor);
  43. visitor.visit(m_detach_key);
  44. }
  45. // 25.1.2.1 AllocateArrayBuffer ( constructor, byteLength ), https://tc39.es/ecma262/#sec-allocatearraybuffer
  46. ThrowCompletionOr<ArrayBuffer*> allocate_array_buffer(GlobalObject& global_object, FunctionObject& constructor, size_t byte_length)
  47. {
  48. // 1. Let obj be ? OrdinaryCreateFromConstructor(constructor, "%ArrayBuffer.prototype%", « [[ArrayBufferData]], [[ArrayBufferByteLength]], [[ArrayBufferDetachKey]] »).
  49. auto* obj = TRY(ordinary_create_from_constructor<ArrayBuffer>(global_object, constructor, &GlobalObject::array_buffer_prototype, nullptr));
  50. // 2. Let block be ? CreateByteDataBlock(byteLength).
  51. auto block = ByteBuffer::create_zeroed(byte_length);
  52. if (block.is_error())
  53. return global_object.vm().throw_completion<RangeError>(global_object, ErrorType::NotEnoughMemoryToAllocate, byte_length);
  54. // 3. Set obj.[[ArrayBufferData]] to block.
  55. obj->set_buffer(block.release_value());
  56. // 4. Set obj.[[ArrayBufferByteLength]] to byteLength.
  57. // 5. Return obj.
  58. return obj;
  59. }
  60. }