1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 07:47:37 +00:00

LibWeb: Fix IDL getter for ReadableByteStreamController byobRequest

We were previously only returning the controllers current
[[byobRequest]] instead of taking into account pending pull intos.

Rename the getter function which would return the controllers
[[byobRequest]] slot to `raw_byob_request` to differentiate it from
the IDL getter.

This also leaves a FIXME for a spec step which we are also not currently
implementing correctly.
This commit is contained in:
Shannon Booth 2023-12-02 20:13:34 +13:00 committed by Andreas Kling
parent 1e607f5775
commit 9d0700e770
4 changed files with 52 additions and 5 deletions

View file

@ -505,7 +505,7 @@ void readable_byte_stream_controller_fill_head_pull_into_descriptor(ReadableByte
VERIFY(controller.pending_pull_intos().is_empty() || &controller.pending_pull_intos().first() == &pull_into_descriptor);
// 2. Assert: controller.[[byobRequest]] is null.
VERIFY(!controller.byob_request());
VERIFY(!controller.raw_byob_request());
// 3. Set pullIntoDescriptors bytes filled to bytes filled + size.
pull_into_descriptor.bytes_filled += size;
@ -1057,6 +1057,38 @@ bool readable_stream_default_controller_should_call_pull(ReadableStreamDefaultCo
return false;
}
// https://streams.spec.whatwg.org/#abstract-opdef-readablebytestreamcontrollergetbyobrequest
JS::GCPtr<ReadableStreamBYOBRequest> readable_byte_stream_controller_get_byob_request(JS::NonnullGCPtr<ReadableByteStreamController> controller)
{
auto& vm = controller->vm();
auto& realm = controller->realm();
// 1. If controller.[[byobRequest]] is null and controller.[[pendingPullIntos]] is not empty,
if (!controller->raw_byob_request() && !controller->pending_pull_intos().is_empty()) {
// 1. Let firstDescriptor be controller.[[pendingPullIntos]][0].
auto const& first_descriptor = controller->pending_pull_intos().first();
// 2. Let view be ! Construct(%Uint8Array%, « firstDescriptors buffer, firstDescriptors byte offset + firstDescriptors bytes filled, firstDescriptors byte length firstDescriptors bytes filled »).
auto view = MUST(JS::construct(vm, *realm.intrinsics().uint8_array_constructor(), first_descriptor.buffer, JS::Value(first_descriptor.byte_offset + first_descriptor.bytes_filled), JS::Value(first_descriptor.byte_length - first_descriptor.bytes_filled)));
// 3. Let byobRequest be a new ReadableStreamBYOBRequest.
auto byob_request = realm.heap().allocate<ReadableStreamBYOBRequest>(realm, realm);
// 4. Set byobRequest.[[controller]] to controller.
byob_request->set_controller(controller);
// 5. Set byobRequest.[[view]] to view.
auto array_buffer_view = vm.heap().allocate<WebIDL::ArrayBufferView>(realm, view);
byob_request->set_view(array_buffer_view);
// 6. Set controller.[[byobRequest]] to byobRequest.
controller->set_byob_request(byob_request);
}
// 2. Return controller.[[byobRequest]].
return controller->raw_byob_request();
}
// https://streams.spec.whatwg.org/#readable-stream-default-controller-clear-algorithms
void readable_stream_default_controller_clear_algorithms(ReadableStreamDefaultController& controller)
{
@ -1813,7 +1845,8 @@ WebIDL::ExceptionOr<void> readable_stream_enqueue(ReadableStreamController& cont
// FIXME: 2. Assert: chunk is an ArrayBufferView.
// 3. Let byobView be the current BYOB request view for stream.
auto byob_view = readable_byte_controller->byob_request();
// FIXME: This is not what the spec means by 'current BYOB request view'
auto byob_view = readable_byte_controller->raw_byob_request();
// 4. If byobView is non-null, and chunk.[[ViewedArrayBuffer]] is byobView.[[ViewedArrayBuffer]], then:
if (byob_view) {
@ -2112,7 +2145,7 @@ WebIDL::ExceptionOr<void> readable_byte_stream_controller_enqueue_cloned_chunk_t
PullIntoDescriptor readable_byte_stream_controller_shift_pending_pull_into(ReadableByteStreamController& controller)
{
// 1. Assert: controller.[[byobRequest]] is null.
VERIFY(!controller.byob_request());
VERIFY(!controller.raw_byob_request());
// 2. Let descriptor be controller.[[pendingPullIntos]][0].
// 3. Remove descriptor from controller.[[pendingPullIntos]].

View file

@ -78,6 +78,7 @@ WebIDL::ExceptionOr<void> set_up_readable_stream_default_controller_from_underly
WebIDL::ExceptionOr<void> set_up_readable_stream_controller_with_byte_reading_support(ReadableStream&, Optional<PullAlgorithm>&& = {}, Optional<CancelAlgorithm>&& = {}, double high_water_mark = 0);
WebIDL::ExceptionOr<void> set_up_readable_byte_stream_controller(ReadableStream&, ReadableByteStreamController&, StartAlgorithm&&, PullAlgorithm&&, CancelAlgorithm&&, double high_water_mark, JS::Value auto_allocate_chunk_size);
WebIDL::ExceptionOr<void> set_up_readable_byte_stream_controller_from_underlying_source(ReadableStream&, JS::Value underlying_source, UnderlyingSource const& underlying_source_dict, double high_water_mark);
JS::GCPtr<ReadableStreamBYOBRequest> readable_byte_stream_controller_get_byob_request(JS::NonnullGCPtr<ReadableByteStreamController>);
WebIDL::ExceptionOr<void> readable_stream_enqueue(ReadableStreamController& controller, JS::Value chunk);
WebIDL::ExceptionOr<void> readable_byte_stream_controller_enqueue(ReadableByteStreamController& controller, JS::Value chunk);

View file

@ -6,6 +6,7 @@
*/
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Streams/AbstractOperations.h>
#include <LibWeb/Streams/ReadableByteStreamController.h>
#include <LibWeb/Streams/ReadableStream.h>
#include <LibWeb/Streams/ReadableStreamBYOBRequest.h>
@ -22,6 +23,13 @@ Optional<double> ReadableByteStreamController::desired_size() const
return readable_byte_stream_controller_get_desired_size(*this);
}
// https://streams.spec.whatwg.org/#rbs-controller-byob-request
JS::GCPtr<ReadableStreamBYOBRequest> ReadableByteStreamController::byob_request()
{
// 1. Return ! ReadableByteStreamControllerGetBYOBRequest(this).
return readable_byte_stream_controller_get_byob_request(*this);
}
// https://streams.spec.whatwg.org/#rbs-controller-close
WebIDL::ExceptionOr<void> ReadableByteStreamController::close()
{

View file

@ -77,10 +77,15 @@ class ReadableByteStreamController : public Bindings::PlatformObject {
public:
virtual ~ReadableByteStreamController() override = default;
JS::GCPtr<ReadableStreamBYOBRequest const> byob_request() const { return m_byob_request; }
JS::GCPtr<ReadableStreamBYOBRequest> byob_request() { return m_byob_request; }
// IDL getter, returns current [[byobRequest]] (if any), and otherwise the [[byobRequest]] for the next pending pull into request
JS::GCPtr<ReadableStreamBYOBRequest> byob_request();
void set_byob_request(JS::GCPtr<ReadableStreamBYOBRequest> request) { m_byob_request = request; }
// Raw [[byobRequest]] slot
JS::GCPtr<ReadableStreamBYOBRequest const> raw_byob_request() const { return m_byob_request; }
JS::GCPtr<ReadableStreamBYOBRequest> raw_byob_request() { return m_byob_request; }
Optional<double> desired_size() const;
WebIDL::ExceptionOr<void> close();
void error(JS::Value error);