From 93f258deb7672a9e72a0a3d63d25cdf9c164c35f Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Sun, 8 Dec 2024 17:39:04 +1300 Subject: [PATCH] LibWeb/Streams: Do not expose some non-standard functions in header These are non-standard and only needed internally as implementation details in the implementation of AbstractOperations, so let's keep them at a file-local level. --- .../LibWeb/Streams/AbstractOperations.cpp | 94 +++++++++---------- Libraries/LibWeb/Streams/AbstractOperations.h | 3 - 2 files changed, 47 insertions(+), 50 deletions(-) diff --git a/Libraries/LibWeb/Streams/AbstractOperations.cpp b/Libraries/LibWeb/Streams/AbstractOperations.cpp index a77b5fd7293..539dd745324 100644 --- a/Libraries/LibWeb/Streams/AbstractOperations.cpp +++ b/Libraries/LibWeb/Streams/AbstractOperations.cpp @@ -45,6 +45,53 @@ namespace Web::Streams { +// https://streams.spec.whatwg.org/#close-sentinel +// Non-standard function that implements the "close sentinel" value. +static JS::Value create_close_sentinel() +{ + // The close sentinel is a unique value enqueued into [[queue]], in lieu of a chunk, to signal that the stream is closed. It is only used internally, and is never exposed to web developers. + // Note: We use the empty Value to signal this as, similarly to the note above, the empty value is not exposed to nor creatable by web developers. + return {}; +} + +// https://streams.spec.whatwg.org/#close-sentinel +// Non-standard function that implements the "If value is a close sentinel" check. +static bool is_close_sentinel(JS::Value value) +{ + return value.is_empty(); +} + +// NON-STANDARD: Can be used instead of CreateReadableStream in cases where we need to set up a newly allocated +// ReadableStream before initialization of said ReadableStream, i.e. ReadableStream is captured by lambdas in an uninitialized state. +// Spec steps are taken from: https://streams.spec.whatwg.org/#create-readable-stream +static WebIDL::ExceptionOr set_up_readable_stream(JS::Realm& realm, ReadableStream& stream, GC::Ref start_algorithm, GC::Ref pull_algorithm, GC::Ref cancel_algorithm, Optional high_water_mark = {}, GC::Ptr size_algorithm = {}) +{ + // 1. If highWaterMark was not passed, set it to 1. + if (!high_water_mark.has_value()) + high_water_mark = 1.0; + + // 2. If sizeAlgorithm was not passed, set it to an algorithm that returns 1. + if (!size_algorithm) + size_algorithm = GC::create_function(realm.heap(), [](JS::Value) { return JS::normal_completion(JS::Value(1)); }); + + // 3. Assert: ! IsNonNegativeNumber(highWaterMark) is true. + VERIFY(is_non_negative_number(JS::Value { *high_water_mark })); + + // 4. Let stream be a new ReadableStream. + // NOTE: The ReadableStream is allocated outside the scope of this method. + + // 5. Perform ! InitializeReadableStream(stream). + initialize_readable_stream(stream); + + // 6. Let controller be a new ReadableStreamDefaultController. + auto controller = realm.create(realm); + + // 7. Perform ? SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm). + TRY(set_up_readable_stream_default_controller(stream, *controller, start_algorithm, pull_algorithm, cancel_algorithm, *high_water_mark, *size_algorithm)); + + return {}; +} + // https://streams.spec.whatwg.org/#acquire-readable-stream-reader WebIDL::ExceptionOr> acquire_readable_stream_default_reader(ReadableStream& stream) { @@ -2932,37 +2979,6 @@ bool readable_byte_stream_controller_should_call_pull(ReadableByteStreamControll return false; } -// NON-STANDARD: Can be used instead of CreateReadableStream in cases where we need to set up a newly allocated -// ReadableStream before initialization of said ReadableStream, i.e. ReadableStream is captured by lambdas in an uninitialized state. -// Spec steps are taken from: https://streams.spec.whatwg.org/#create-readable-stream -WebIDL::ExceptionOr set_up_readable_stream(JS::Realm& realm, ReadableStream& stream, GC::Ref start_algorithm, GC::Ref pull_algorithm, GC::Ref cancel_algorithm, Optional high_water_mark, GC::Ptr size_algorithm) -{ - // 1. If highWaterMark was not passed, set it to 1. - if (!high_water_mark.has_value()) - high_water_mark = 1.0; - - // 2. If sizeAlgorithm was not passed, set it to an algorithm that returns 1. - if (!size_algorithm) - size_algorithm = GC::create_function(realm.heap(), [](JS::Value) { return JS::normal_completion(JS::Value(1)); }); - - // 3. Assert: ! IsNonNegativeNumber(highWaterMark) is true. - VERIFY(is_non_negative_number(JS::Value { *high_water_mark })); - - // 4. Let stream be a new ReadableStream. - // NOTE: The ReadableStream is allocated outside the scope of this method. - - // 5. Perform ! InitializeReadableStream(stream). - initialize_readable_stream(stream); - - // 6. Let controller be a new ReadableStreamDefaultController. - auto controller = realm.create(realm); - - // 7. Perform ? SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm). - TRY(set_up_readable_stream_default_controller(stream, *controller, start_algorithm, pull_algorithm, cancel_algorithm, *high_water_mark, *size_algorithm)); - - return {}; -} - // https://streams.spec.whatwg.org/#create-readable-stream WebIDL::ExceptionOr> create_readable_stream(JS::Realm& realm, GC::Ref start_algorithm, GC::Ref pull_algorithm, GC::Ref cancel_algorithm, Optional high_water_mark, GC::Ptr size_algorithm) { @@ -5286,22 +5302,6 @@ WebIDL::ExceptionOr structured_clone(JS::Realm& realm, JS::Value valu return TRY(HTML::structured_deserialize(vm, serialized, realm)); } -// https://streams.spec.whatwg.org/#close-sentinel -// Non-standard function that implements the "close sentinel" value. -JS::Value create_close_sentinel() -{ - // The close sentinel is a unique value enqueued into [[queue]], in lieu of a chunk, to signal that the stream is closed. It is only used internally, and is never exposed to web developers. - // Note: We use the empty Value to signal this as, similarly to the note above, the empty value is not exposed to nor creatable by web developers. - return {}; -} - -// https://streams.spec.whatwg.org/#close-sentinel -// Non-standard function that implements the "If value is a close sentinel" check. -bool is_close_sentinel(JS::Value value) -{ - return value.is_empty(); -} - // Non-standard function to aid in converting a user-provided function into a WebIDL::Callback. This is essentially // what the Bindings generator would do at compile time, but at runtime instead. JS::ThrowCompletionOr> property_to_callback(JS::VM& vm, JS::Value value, JS::PropertyKey const& property_key, WebIDL::OperationReturnsPromise operation_returns_promise) diff --git a/Libraries/LibWeb/Streams/AbstractOperations.h b/Libraries/LibWeb/Streams/AbstractOperations.h index 7229f554983..ef8a16808ef 100644 --- a/Libraries/LibWeb/Streams/AbstractOperations.h +++ b/Libraries/LibWeb/Streams/AbstractOperations.h @@ -106,7 +106,6 @@ void readable_byte_stream_controller_handle_queue_drain(ReadableByteStreamContro void readable_byte_stream_controller_invalidate_byob_request(ReadableByteStreamController&); bool readable_byte_stream_controller_should_call_pull(ReadableByteStreamController const&); -WebIDL::ExceptionOr set_up_readable_stream(JS::Realm& realm, ReadableStream& stream, GC::Ref start_algorithm, GC::Ref pull_algorithm, GC::Ref cancel_algorithm, Optional high_water_mark = {}, GC::Ptr size_algorithm = {}); WebIDL::ExceptionOr> create_readable_stream(JS::Realm& realm, GC::Ref start_algorithm, GC::Ref pull_algorithm, GC::Ref cancel_algorithm, Optional high_water_mark = {}, GC::Ptr size_algorithm = {}); WebIDL::ExceptionOr> create_readable_byte_stream(JS::Realm& realm, GC::Ref start_algorithm, GC::Ref pull_algorithm, GC::Ref cancel_algorithm); WebIDL::ExceptionOr> create_writable_stream(JS::Realm& realm, GC::Ref start_algorithm, GC::Ref write_algorithm, GC::Ref close_algorithm, GC::Ref abort_algorithm, double high_water_mark, GC::Ref size_algorithm); @@ -180,8 +179,6 @@ bool can_transfer_array_buffer(JS::ArrayBuffer const& array_buffer); WebIDL::ExceptionOr clone_as_uint8_array(JS::Realm&, WebIDL::ArrayBufferView&); WebIDL::ExceptionOr structured_clone(JS::Realm&, JS::Value value); -JS::Value create_close_sentinel(); -bool is_close_sentinel(JS::Value); JS::ThrowCompletionOr> property_to_callback(JS::VM& vm, JS::Value value, JS::PropertyKey const& property_key, WebIDL::OperationReturnsPromise); // https://streams.spec.whatwg.org/#value-with-size