From 7b0f4d0f1ace7ab32aec28c2f03662af90f6b7a0 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Thu, 17 Apr 2025 20:09:43 -0400 Subject: [PATCH] LibWeb: Sort remaining stream AOs (mostly) in spec order The remaining AOs can stay where they are. This patch just sorts them in spec order to match the other AO files. Section 8.1 is last, however, as these are all templates and need the declarations of other AOs above. --- .../LibWeb/Streams/AbstractOperations.cpp | 138 +++++++++--------- Libraries/LibWeb/Streams/AbstractOperations.h | 15 +- 2 files changed, 78 insertions(+), 75 deletions(-) diff --git a/Libraries/LibWeb/Streams/AbstractOperations.cpp b/Libraries/LibWeb/Streams/AbstractOperations.cpp index 4382e02a8f8..6396b3e2716 100644 --- a/Libraries/LibWeb/Streams/AbstractOperations.cpp +++ b/Libraries/LibWeb/Streams/AbstractOperations.cpp @@ -18,20 +18,6 @@ namespace Web::Streams { -// https://streams.spec.whatwg.org/#make-size-algorithm-from-size-function -GC::Ref extract_size_algorithm(JS::VM& vm, QueuingStrategy const& strategy) -{ - // 1. If strategy["size"] does not exist, return an algorithm that returns 1. - if (!strategy.size) - return GC::create_function(vm.heap(), [](JS::Value) { return JS::normal_completion(JS::Value(1)); }); - - // 2. Return an algorithm that performs the following steps, taking a chunk argument: - return GC::create_function(vm.heap(), [size = strategy.size](JS::Value chunk) { - // 1. Return the result of invoking strategy["size"] with argument list « chunk ». - return WebIDL::invoke_callback(*size, {}, { { chunk } }); - }); -} - // https://streams.spec.whatwg.org/#validate-and-normalize-high-water-mark WebIDL::ExceptionOr extract_high_water_mark(QueuingStrategy const& strategy, double default_hwm) { @@ -50,23 +36,36 @@ WebIDL::ExceptionOr extract_high_water_mark(QueuingStrategy const& strat return high_water_mark; } -// https://streams.spec.whatwg.org/#transfer-array-buffer -WebIDL::ExceptionOr> transfer_array_buffer(JS::Realm& realm, JS::ArrayBuffer& buffer) +// https://streams.spec.whatwg.org/#make-size-algorithm-from-size-function +GC::Ref extract_size_algorithm(JS::VM& vm, QueuingStrategy const& strategy) { - auto& vm = realm.vm(); + // 1. If strategy["size"] does not exist, return an algorithm that returns 1. + if (!strategy.size) + return GC::create_function(vm.heap(), [](JS::Value) { return JS::normal_completion(JS::Value(1)); }); - // 1. Assert: ! IsDetachedBuffer(O) is false. - VERIFY(!buffer.is_detached()); + // 2. Return an algorithm that performs the following steps, taking a chunk argument: + return GC::create_function(vm.heap(), [size = strategy.size](JS::Value chunk) { + // 1. Return the result of invoking strategy["size"] with argument list « chunk ». + return WebIDL::invoke_callback(*size, {}, { { chunk } }); + }); +} - // 2. Let arrayBufferData be O.[[ArrayBufferData]]. - // 3. Let arrayBufferByteLength be O.[[ArrayBufferByteLength]]. - auto array_buffer = buffer.buffer(); +// https://streams.spec.whatwg.org/#can-transfer-array-buffer +bool can_transfer_array_buffer(JS::ArrayBuffer const& array_buffer) +{ + // 1. Assert: O is an Object. + // 2. Assert: O has an [[ArrayBufferData]] internal slot. - // 4. Perform ? DetachArrayBuffer(O). - TRY(JS::detach_array_buffer(vm, buffer)); + // 3. If ! IsDetachedBuffer(O) is true, return false. + if (array_buffer.is_detached()) + return false; - // 5. Return a new ArrayBuffer object, created in the current Realm, whose [[ArrayBufferData]] internal slot value is arrayBufferData and whose [[ArrayBufferByteLength]] internal slot value is arrayBufferByteLength. - return JS::ArrayBuffer::create(realm, move(array_buffer)); + // 4. If SameValue(O.[[ArrayBufferDetachKey]], undefined) is false, return false. + if (!JS::same_value(array_buffer.detach_key(), JS::js_undefined())) + return false; + + // 5. Return true. + return true; } // https://streams.spec.whatwg.org/#is-non-negative-number @@ -88,54 +87,23 @@ bool is_non_negative_number(JS::Value value) return true; } -// https://streams.spec.whatwg.org/#abstract-opdef-cancopydatablockbytes -bool can_copy_data_block_bytes_buffer(JS::ArrayBuffer const& to_buffer, u64 to_index, JS::ArrayBuffer const& from_buffer, u64 from_index, u64 count) +// https://streams.spec.whatwg.org/#transfer-array-buffer +WebIDL::ExceptionOr> transfer_array_buffer(JS::Realm& realm, JS::ArrayBuffer& buffer) { - // 1. Assert: toBuffer is an Object. - // 2. Assert: toBuffer has an [[ArrayBufferData]] internal slot. - // 3. Assert: fromBuffer is an Object. - // 4. Assert: fromBuffer has an [[ArrayBufferData]] internal slot. + auto& vm = realm.vm(); - // 5. If toBuffer is fromBuffer, return false. - if (&to_buffer == &from_buffer) - return false; + // 1. Assert: ! IsDetachedBuffer(O) is false. + VERIFY(!buffer.is_detached()); - // 6. If ! IsDetachedBuffer(toBuffer) is true, return false. - if (to_buffer.is_detached()) - return false; + // 2. Let arrayBufferData be O.[[ArrayBufferData]]. + // 3. Let arrayBufferByteLength be O.[[ArrayBufferByteLength]]. + auto array_buffer = buffer.buffer(); - // 7. If ! IsDetachedBuffer(fromBuffer) is true, return false. - if (from_buffer.is_detached()) - return false; + // 4. Perform ? DetachArrayBuffer(O). + TRY(JS::detach_array_buffer(vm, buffer)); - // 8. If toIndex + count > toBuffer.[[ArrayBufferByteLength]], return false. - if (to_index + count > to_buffer.byte_length()) - return false; - - // 9. If fromIndex + count > fromBuffer.[[ArrayBufferByteLength]], return false. - if (from_index + count > from_buffer.byte_length()) - return false; - - // 10. Return true. - return true; -} - -// https://streams.spec.whatwg.org/#can-transfer-array-buffer -bool can_transfer_array_buffer(JS::ArrayBuffer const& array_buffer) -{ - // 1. Assert: O is an Object. - // 2. Assert: O has an [[ArrayBufferData]] internal slot. - - // 3. If ! IsDetachedBuffer(O) is true, return false. - if (array_buffer.is_detached()) - return false; - - // 4. If SameValue(O.[[ArrayBufferDetachKey]], undefined) is false, return false. - if (!JS::same_value(array_buffer.detach_key(), JS::js_undefined())) - return false; - - // 5. Return true. - return true; + // 5. Return a new ArrayBuffer object, created in the current Realm, whose [[ArrayBufferData]] internal slot value is arrayBufferData and whose [[ArrayBufferByteLength]] internal slot value is arrayBufferByteLength. + return JS::ArrayBuffer::create(realm, move(array_buffer)); } // https://streams.spec.whatwg.org/#abstract-opdef-cloneasuint8array @@ -171,4 +139,36 @@ WebIDL::ExceptionOr structured_clone(JS::Realm& realm, JS::Value valu return TRY(HTML::structured_deserialize(vm, serialized, realm)); } +// https://streams.spec.whatwg.org/#abstract-opdef-cancopydatablockbytes +bool can_copy_data_block_bytes_buffer(JS::ArrayBuffer const& to_buffer, u64 to_index, JS::ArrayBuffer const& from_buffer, u64 from_index, u64 count) +{ + // 1. Assert: toBuffer is an Object. + // 2. Assert: toBuffer has an [[ArrayBufferData]] internal slot. + // 3. Assert: fromBuffer is an Object. + // 4. Assert: fromBuffer has an [[ArrayBufferData]] internal slot. + + // 5. If toBuffer is fromBuffer, return false. + if (&to_buffer == &from_buffer) + return false; + + // 6. If ! IsDetachedBuffer(toBuffer) is true, return false. + if (to_buffer.is_detached()) + return false; + + // 7. If ! IsDetachedBuffer(fromBuffer) is true, return false. + if (from_buffer.is_detached()) + return false; + + // 8. If toIndex + count > toBuffer.[[ArrayBufferByteLength]], return false. + if (to_index + count > to_buffer.byte_length()) + return false; + + // 9. If fromIndex + count > fromBuffer.[[ArrayBufferByteLength]], return false. + if (from_index + count > from_buffer.byte_length()) + return false; + + // 10. Return true. + return true; +} + } diff --git a/Libraries/LibWeb/Streams/AbstractOperations.h b/Libraries/LibWeb/Streams/AbstractOperations.h index 9ed419b8077..d22586f05ee 100644 --- a/Libraries/LibWeb/Streams/AbstractOperations.h +++ b/Libraries/LibWeb/Streams/AbstractOperations.h @@ -17,21 +17,24 @@ namespace Web::Streams { -GC::Ref extract_size_algorithm(JS::VM&, QueuingStrategy const&); +// 7.4. Abstract operations, https://streams.spec.whatwg.org/#qs-abstract-ops WebIDL::ExceptionOr extract_high_water_mark(QueuingStrategy const&, double default_hwm); +GC::Ref extract_size_algorithm(JS::VM&, QueuingStrategy const&); -WebIDL::ExceptionOr> transfer_array_buffer(JS::Realm& realm, JS::ArrayBuffer& buffer); - -bool is_non_negative_number(JS::Value); -bool can_copy_data_block_bytes_buffer(JS::ArrayBuffer const& to_buffer, u64 to_index, JS::ArrayBuffer const& from_buffer, u64 from_index, u64 count); +// 8.3. Miscellaneous, https://streams.spec.whatwg.org/#misc-abstract-ops bool can_transfer_array_buffer(JS::ArrayBuffer const& array_buffer); +bool is_non_negative_number(JS::Value); +WebIDL::ExceptionOr> transfer_array_buffer(JS::Realm& realm, JS::ArrayBuffer& buffer); WebIDL::ExceptionOr clone_as_uint8_array(JS::Realm&, WebIDL::ArrayBufferView&); WebIDL::ExceptionOr structured_clone(JS::Realm&, JS::Value value); +bool can_copy_data_block_bytes_buffer(JS::ArrayBuffer const& to_buffer, u64 to_index, JS::ArrayBuffer const& from_buffer, u64 from_index, u64 count); + +// 8.1. Queue-with-sizes, https://streams.spec.whatwg.org/#queue-with-sizes // https://streams.spec.whatwg.org/#value-with-size struct ValueWithSize { JS::Value value; - double size; + double size { 0 }; }; // https://streams.spec.whatwg.org/#dequeue-value