From 19bbfb023ab0d94daef30a2c04d7b7ab1011d317 Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Sun, 8 Dec 2024 17:35:07 +1300 Subject: [PATCH] LibWeb/Streams: Move "set up transform stream" to TransformStream This is not marked as an AO in the spec, and is a publically exported API exposed on TransformStream. --- .../LibWeb/Compression/CompressionStream.cpp | 2 +- .../Compression/DecompressionStream.cpp | 2 +- Libraries/LibWeb/Fetch/Fetching/Fetching.cpp | 2 +- .../LibWeb/Streams/AbstractOperations.cpp | 78 ------------------- Libraries/LibWeb/Streams/AbstractOperations.h | 1 - Libraries/LibWeb/Streams/TransformStream.cpp | 78 +++++++++++++++++++ Libraries/LibWeb/Streams/TransformStream.h | 3 + 7 files changed, 84 insertions(+), 82 deletions(-) diff --git a/Libraries/LibWeb/Compression/CompressionStream.cpp b/Libraries/LibWeb/Compression/CompressionStream.cpp index b72bbd8c997..831bc9d6704 100644 --- a/Libraries/LibWeb/Compression/CompressionStream.cpp +++ b/Libraries/LibWeb/Compression/CompressionStream.cpp @@ -76,7 +76,7 @@ WebIDL::ExceptionOr> CompressionStream::construct_imp }); // 6. Set up this's transform with transformAlgorithm set to transformAlgorithm and flushAlgorithm set to flushAlgorithm. - Streams::transform_stream_set_up(stream->m_transform, transform_algorithm, flush_algorithm); + stream->m_transform->set_up(transform_algorithm, flush_algorithm); return stream; } diff --git a/Libraries/LibWeb/Compression/DecompressionStream.cpp b/Libraries/LibWeb/Compression/DecompressionStream.cpp index 1b2b909a8a3..99bae93b155 100644 --- a/Libraries/LibWeb/Compression/DecompressionStream.cpp +++ b/Libraries/LibWeb/Compression/DecompressionStream.cpp @@ -77,7 +77,7 @@ WebIDL::ExceptionOr> DecompressionStream::construct }); // 6. Set up this's transform with transformAlgorithm set to transformAlgorithm and flushAlgorithm set to flushAlgorithm. - Streams::transform_stream_set_up(stream->m_transform, transform_algorithm, flush_algorithm); + stream->m_transform->set_up(transform_algorithm, flush_algorithm); return stream; } diff --git a/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp b/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp index 207f0ad619e..a576937d1dd 100644 --- a/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp +++ b/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp @@ -741,7 +741,7 @@ void fetch_response_handover(JS::Realm& realm, Infrastructure::FetchParams const process_response_end_of_body(); return WebIDL::create_resolved_promise(realm, JS::js_undefined()); }); - Streams::transform_stream_set_up(transform_stream, identity_transform_algorithm, flush_algorithm); + transform_stream->set_up(identity_transform_algorithm, flush_algorithm); // 4. Set internalResponse’s body’s stream to the result of internalResponse’s body’s stream piped through transformStream. auto promise = Streams::readable_stream_pipe_to(internal_response->body()->stream(), transform_stream->writable(), false, false, false, {}); diff --git a/Libraries/LibWeb/Streams/AbstractOperations.cpp b/Libraries/LibWeb/Streams/AbstractOperations.cpp index b34f2c16208..a77b5fd7293 100644 --- a/Libraries/LibWeb/Streams/AbstractOperations.cpp +++ b/Libraries/LibWeb/Streams/AbstractOperations.cpp @@ -5176,84 +5176,6 @@ void transform_stream_set_backpressure(TransformStream& stream, bool backpressur stream.set_backpressure(backpressure); } -// https://streams.spec.whatwg.org/#transformstream-set-up -void transform_stream_set_up(TransformStream& stream, GC::Ref transform_algorithm, GC::Ptr flush_algorithm, GC::Ptr cancel_algorithm) -{ - auto& realm = stream.realm(); - - // 1. Let writableHighWaterMark be 1. - auto writable_high_water_mark = 1.0; - - // 2. Let writableSizeAlgorithm be an algorithm that returns 1. - auto writable_size_algorithm = GC::create_function(realm.heap(), [](JS::Value) { - return JS::normal_completion(JS::Value { 1 }); - }); - - // 3. Let readableHighWaterMark be 0. - auto readable_high_water_mark = 0.0; - - // 4. Let readableSizeAlgorithm be an algorithm that returns 1. - auto readable_size_algorithm = GC::create_function(realm.heap(), [](JS::Value) { - return JS::normal_completion(JS::Value { 1 }); - }); - - // 5. Let transformAlgorithmWrapper be an algorithm that runs these steps given a value chunk: - auto transform_algorithm_wrapper = GC::create_function(realm.heap(), [&realm, transform_algorithm](JS::Value chunk) -> GC::Ref { - // 1. Let result be the result of running transformAlgorithm given chunk. If this throws an exception e, return a promise rejected with e. - GC::Ptr result = nullptr; - result = transform_algorithm->function()(chunk); - - // 2. If result is a Promise, then return result. - if (result) - return GC::Ref { *result }; - - // 3. Return a promise resolved with undefined. - return WebIDL::create_resolved_promise(realm, JS::js_undefined()); - }); - - // 6. Let flushAlgorithmWrapper be an algorithm that runs these steps: - auto flush_algorithm_wrapper = GC::create_function(realm.heap(), [&realm, flush_algorithm]() -> GC::Ref { - // 1. Let result be the result of running flushAlgorithm, if flushAlgorithm was given, or null otherwise. If this throws an exception e, return a promise rejected with e. - GC::Ptr result = nullptr; - if (flush_algorithm) - result = flush_algorithm->function()(); - - // 2. If result is a Promise, then return result. - if (result) - return GC::Ref { *result }; - - // 3. Return a promise resolved with undefined. - return WebIDL::create_resolved_promise(realm, JS::js_undefined()); - }); - - // 7. Let cancelAlgorithmWrapper be an algorithm that runs these steps given a value reason: - auto cancel_algorithm_wrapper = GC::create_function(realm.heap(), [&realm, cancel_algorithm](JS::Value reason) -> GC::Ref { - // 1. Let result be the result of running cancelAlgorithm given reason, if cancelAlgorithm was given, or null otherwise. If this throws an exception e, return a promise rejected with e. - GC::Ptr result = nullptr; - if (cancel_algorithm) - result = cancel_algorithm->function()(reason); - - // 2. If result is a Promise, then return result. - if (result) - return GC::Ref { *result }; - - // 3. Return a promise resolved with undefined. - return WebIDL::create_resolved_promise(realm, JS::js_undefined()); - }); - - // 8. Let startPromise be a promise resolved with undefined. - auto start_promise = WebIDL::create_resolved_promise(realm, JS::js_undefined()); - - // 9. Perform ! InitializeTransformStream(stream, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm). - initialize_transform_stream(stream, start_promise, writable_high_water_mark, writable_size_algorithm, readable_high_water_mark, readable_size_algorithm); - - // 10. Let controller be a new TransformStreamDefaultController. - auto controller = realm.create(realm); - - // 11. Perform ! SetUpTransformStreamDefaultController(stream, controller, transformAlgorithmWrapper, flushAlgorithmWrapper, cancelAlgorithmWrapper). - set_up_transform_stream_default_controller(stream, controller, transform_algorithm_wrapper, flush_algorithm_wrapper, cancel_algorithm_wrapper); -} - // https://streams.spec.whatwg.org/#transform-stream-unblock-write void transform_stream_unblock_write(TransformStream& stream) { diff --git a/Libraries/LibWeb/Streams/AbstractOperations.h b/Libraries/LibWeb/Streams/AbstractOperations.h index dceac54b5c9..7229f554983 100644 --- a/Libraries/LibWeb/Streams/AbstractOperations.h +++ b/Libraries/LibWeb/Streams/AbstractOperations.h @@ -172,7 +172,6 @@ GC::Ref transform_stream_default_source_cancel_algorithm(Transf void transform_stream_error(TransformStream&, JS::Value error); void transform_stream_error_writable_and_unblock_write(TransformStream&, JS::Value error); void transform_stream_set_backpressure(TransformStream&, bool backpressure); -void transform_stream_set_up(TransformStream&, GC::Ref, GC::Ptr = {}, GC::Ptr = {}); void transform_stream_unblock_write(TransformStream&); bool is_non_negative_number(JS::Value); diff --git a/Libraries/LibWeb/Streams/TransformStream.cpp b/Libraries/LibWeb/Streams/TransformStream.cpp index 2387e6bc3f2..125ff3acae9 100644 --- a/Libraries/LibWeb/Streams/TransformStream.cpp +++ b/Libraries/LibWeb/Streams/TransformStream.cpp @@ -74,6 +74,84 @@ WebIDL::ExceptionOr> TransformStream::construct_impl(JS return stream; } +// https://streams.spec.whatwg.org/#transformstream-set-up +void TransformStream::set_up(GC::Ref transform_algorithm, GC::Ptr flush_algorithm, GC::Ptr cancel_algorithm) +{ + auto& realm = this->realm(); + + // 1. Let writableHighWaterMark be 1. + auto writable_high_water_mark = 1.0; + + // 2. Let writableSizeAlgorithm be an algorithm that returns 1. + auto writable_size_algorithm = GC::create_function(realm.heap(), [](JS::Value) { + return JS::normal_completion(JS::Value { 1 }); + }); + + // 3. Let readableHighWaterMark be 0. + auto readable_high_water_mark = 0.0; + + // 4. Let readableSizeAlgorithm be an algorithm that returns 1. + auto readable_size_algorithm = GC::create_function(realm.heap(), [](JS::Value) { + return JS::normal_completion(JS::Value { 1 }); + }); + + // 5. Let transformAlgorithmWrapper be an algorithm that runs these steps given a value chunk: + auto transform_algorithm_wrapper = GC::create_function(realm.heap(), [&realm, transform_algorithm](JS::Value chunk) -> GC::Ref { + // 1. Let result be the result of running transformAlgorithm given chunk. If this throws an exception e, return a promise rejected with e. + GC::Ptr result = nullptr; + result = transform_algorithm->function()(chunk); + + // 2. If result is a Promise, then return result. + if (result) + return GC::Ref { *result }; + + // 3. Return a promise resolved with undefined. + return WebIDL::create_resolved_promise(realm, JS::js_undefined()); + }); + + // 6. Let flushAlgorithmWrapper be an algorithm that runs these steps: + auto flush_algorithm_wrapper = GC::create_function(realm.heap(), [&realm, flush_algorithm]() -> GC::Ref { + // 1. Let result be the result of running flushAlgorithm, if flushAlgorithm was given, or null otherwise. If this throws an exception e, return a promise rejected with e. + GC::Ptr result = nullptr; + if (flush_algorithm) + result = flush_algorithm->function()(); + + // 2. If result is a Promise, then return result. + if (result) + return GC::Ref { *result }; + + // 3. Return a promise resolved with undefined. + return WebIDL::create_resolved_promise(realm, JS::js_undefined()); + }); + + // 7. Let cancelAlgorithmWrapper be an algorithm that runs these steps given a value reason: + auto cancel_algorithm_wrapper = GC::create_function(realm.heap(), [&realm, cancel_algorithm](JS::Value reason) -> GC::Ref { + // 1. Let result be the result of running cancelAlgorithm given reason, if cancelAlgorithm was given, or null otherwise. If this throws an exception e, return a promise rejected with e. + GC::Ptr result = nullptr; + if (cancel_algorithm) + result = cancel_algorithm->function()(reason); + + // 2. If result is a Promise, then return result. + if (result) + return GC::Ref { *result }; + + // 3. Return a promise resolved with undefined. + return WebIDL::create_resolved_promise(realm, JS::js_undefined()); + }); + + // 8. Let startPromise be a promise resolved with undefined. + auto start_promise = WebIDL::create_resolved_promise(realm, JS::js_undefined()); + + // 9. Perform ! InitializeTransformStream(stream, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm). + initialize_transform_stream(*this, start_promise, writable_high_water_mark, writable_size_algorithm, readable_high_water_mark, readable_size_algorithm); + + // 10. Let controller be a new TransformStreamDefaultController. + auto controller = realm.create(realm); + + // 11. Perform ! SetUpTransformStreamDefaultController(stream, controller, transformAlgorithmWrapper, flushAlgorithmWrapper, cancelAlgorithmWrapper). + set_up_transform_stream_default_controller(*this, controller, transform_algorithm_wrapper, flush_algorithm_wrapper, cancel_algorithm_wrapper); +} + TransformStream::TransformStream(JS::Realm& realm) : Bindings::PlatformObject(realm) { diff --git a/Libraries/LibWeb/Streams/TransformStream.h b/Libraries/LibWeb/Streams/TransformStream.h index a1ba305222f..753ff12eafe 100644 --- a/Libraries/LibWeb/Streams/TransformStream.h +++ b/Libraries/LibWeb/Streams/TransformStream.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -40,6 +41,8 @@ public: GC::Ptr controller() const { return m_controller; } void set_controller(GC::Ptr value) { m_controller = value; } + void set_up(GC::Ref, GC::Ptr = {}, GC::Ptr = {}); + private: explicit TransformStream(JS::Realm& realm);