diff options
author | Timothy Flynn <trflynn89@pm.me> | 2022-04-15 11:39:17 -0400 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-04-16 16:49:52 +0100 |
commit | 6654efcd8207811bf3442368bf3cba04ac4ec5ae (patch) | |
tree | 6b0cddd64b7c6099b14d94f021ded60c77710fde | |
parent | 39b308ba524133a197f123a6ef7e7dfba1eaf285 (diff) | |
download | serenity-6654efcd8207811bf3442368bf3cba04ac4ec5ae.zip |
LibJS: Remove cloneConstructor parameter from CloneArrayBuffer
This is a normative change in the ECMA-262 spec. See:
https://github.com/tc39/ecma262/commit/e7979fd
Note that this implements a FIXME in InitializeTypedArrayFromTypedArray,
now that shared array buffers are no longer a concern there. We already
have test coverage for the now-handled case.
4 files changed, 48 insertions, 51 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp index 35766ba9c0..a477113dd2 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp +++ b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp @@ -7,6 +7,7 @@ #include <LibJS/Runtime/AbstractOperations.h> #include <LibJS/Runtime/ArrayBuffer.h> +#include <LibJS/Runtime/ArrayBufferConstructor.h> #include <LibJS/Runtime/GlobalObject.h> namespace JS { @@ -121,16 +122,13 @@ ThrowCompletionOr<Value> detach_array_buffer(GlobalObject& global_object, ArrayB } // 25.1.2.4 CloneArrayBuffer ( srcBuffer, srcByteOffset, srcLength, cloneConstructor ), https://tc39.es/ecma262/#sec-clonearraybuffer -ThrowCompletionOr<ArrayBuffer*> clone_array_buffer(GlobalObject& global_object, ArrayBuffer& source_buffer, size_t source_byte_offset, size_t source_length, FunctionObject& clone_constructor) +ThrowCompletionOr<ArrayBuffer*> clone_array_buffer(GlobalObject& global_object, ArrayBuffer& source_buffer, size_t source_byte_offset, size_t source_length) { - auto& vm = global_object.vm(); - - // 1. Let targetBuffer be ? AllocateArrayBuffer(cloneConstructor, srcLength). - auto* target_buffer = TRY(allocate_array_buffer(global_object, clone_constructor, source_length)); + // 1. Assert: IsDetachedBuffer(srcBuffer) is false. + VERIFY(!source_buffer.is_detached()); - // 2. If IsDetachedBuffer(srcBuffer) is true, throw a TypeError exception. - if (source_buffer.is_detached()) - return vm.throw_completion<TypeError>(global_object, ErrorType::DetachedArrayBuffer); + // 2. Let targetBuffer be ? AllocateArrayBuffer(%ArrayBuffer%, srcLength). + auto* target_buffer = TRY(allocate_array_buffer(global_object, *global_object.array_buffer_constructor(), source_length)); // 3. Let srcBlock be srcBuffer.[[ArrayBufferData]]. auto& source_block = source_buffer.buffer(); diff --git a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h index 0dddc1d1ba..f64a25b7ca 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h +++ b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h @@ -82,7 +82,7 @@ private: ThrowCompletionOr<ArrayBuffer*> allocate_array_buffer(GlobalObject&, FunctionObject& constructor, size_t byte_length, Optional<size_t> max_byte_length = {}); ThrowCompletionOr<Value> detach_array_buffer(GlobalObject&, ArrayBuffer& array_buffer, Optional<Value> key = {}); -ThrowCompletionOr<ArrayBuffer*> clone_array_buffer(GlobalObject&, ArrayBuffer& source_buffer, size_t source_byte_offset, size_t source_length, FunctionObject& clone_constructor); +ThrowCompletionOr<ArrayBuffer*> clone_array_buffer(GlobalObject&, ArrayBuffer& source_buffer, size_t source_byte_offset, size_t source_length); // 25.1.2.9 RawBytesToNumeric ( type, rawBytes, isLittleEndian ), https://tc39.es/ecma262/#sec-rawbytestonumeric template<typename T> diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp index b3f8f3277b..47691a0f12 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp @@ -164,63 +164,64 @@ static ThrowCompletionOr<void> initialize_typed_array_from_typed_array(GlobalObj if (byte_length.has_overflow()) return vm.template throw_completion<RangeError>(global_object, ErrorType::InvalidLength, "typed array"); - // FIXME: - // 10. If IsSharedArrayBuffer(srcData) is false, then - // a. Let bufferConstructor be ? SpeciesConstructor(srcData, %ArrayBuffer%). - // 11. Else, - // a. Let bufferConstructor be %ArrayBuffer%. - // 12. If elementType is the same as srcType, then - // a. Let data be ? CloneArrayBuffer(srcData, srcByteOffset, byteLength, bufferConstructor). - // 13. Else, + ArrayBuffer* data = nullptr; - // a. Let data be ? AllocateArrayBuffer(bufferConstructor, byteLength). - auto* data = TRY(allocate_array_buffer(global_object, *global_object.array_buffer_constructor(), byte_length.value())); + // 10. If elementType is the same as srcType, then + if (dest_array.element_name() == src_array.element_name()) { + // a. Let data be ? CloneArrayBuffer(srcData, srcByteOffset, byteLength). + data = TRY(clone_array_buffer(global_object, *src_data, src_byte_offset, byte_length.value())); + } + // 11. Else, + else { + // a. Let data be ? AllocateArrayBuffer(bufferConstructor, byteLength). + data = TRY(allocate_array_buffer(global_object, *global_object.array_buffer_constructor(), byte_length.value())); - // b. If IsDetachedBuffer(srcData) is true, throw a TypeError exception. - if (src_data->is_detached()) - return vm.template throw_completion<TypeError>(global_object, ErrorType::DetachedArrayBuffer); + // b. If IsDetachedBuffer(srcData) is true, throw a TypeError exception. + if (src_data->is_detached()) + return vm.template throw_completion<TypeError>(global_object, ErrorType::DetachedArrayBuffer); - // c. If srcArray.[[ContentType]] ≠ O.[[ContentType]], throw a TypeError exception. - if (src_array.content_type() != dest_array.content_type()) - return vm.template throw_completion<TypeError>(global_object, ErrorType::TypedArrayContentTypeMismatch, dest_array.class_name(), src_array.class_name()); + // c. If srcArray.[[ContentType]] ≠ O.[[ContentType]], throw a TypeError exception. + if (src_array.content_type() != dest_array.content_type()) + return vm.template throw_completion<TypeError>(global_object, ErrorType::TypedArrayContentTypeMismatch, dest_array.class_name(), src_array.class_name()); - // d. Let srcByteIndex be srcByteOffset. - u64 src_byte_index = src_byte_offset; + // d. Let srcByteIndex be srcByteOffset. + u64 src_byte_index = src_byte_offset; - // e. Let targetByteIndex be 0. - u64 target_byte_index = 0; + // e. Let targetByteIndex be 0. + u64 target_byte_index = 0; - // f. Let count be elementLength. - // g. Repeat, while count > 0, - for (u32 i = 0; i < element_length; ++i) { - // i. Let value be GetValueFromBuffer(srcData, srcByteIndex, srcType, true, Unordered). - auto value = src_array.get_value_from_buffer(src_byte_index, ArrayBuffer::Order::Unordered); + // f. Let count be elementLength. + // g. Repeat, while count > 0, + for (u32 i = 0; i < element_length; ++i) { + // i. Let value be GetValueFromBuffer(srcData, srcByteIndex, srcType, true, Unordered). + auto value = src_array.get_value_from_buffer(src_byte_index, ArrayBuffer::Order::Unordered); - // ii. Perform SetValueInBuffer(data, targetByteIndex, elementType, value, true, Unordered). - data->template set_value<T>(target_byte_index, value, true, ArrayBuffer::Order::Unordered); + // ii. Perform SetValueInBuffer(data, targetByteIndex, elementType, value, true, Unordered). + data->template set_value<T>(target_byte_index, value, true, ArrayBuffer::Order::Unordered); - // iii. Set srcByteIndex to srcByteIndex + srcElementSize. - src_byte_index += src_element_size; + // iii. Set srcByteIndex to srcByteIndex + srcElementSize. + src_byte_index += src_element_size; - // iv. Set targetByteIndex to targetByteIndex + elementSize. - target_byte_index += element_size; + // iv. Set targetByteIndex to targetByteIndex + elementSize. + target_byte_index += element_size; - // v. Set count to count - 1. + // v. Set count to count - 1. + } } - // 14. Set O.[[ViewedArrayBuffer]] to data. + // 12. Set O.[[ViewedArrayBuffer]] to data. dest_array.set_viewed_array_buffer(data); - // 15. Set O.[[ByteLength]] to byteLength. + // 13. Set O.[[ByteLength]] to byteLength. dest_array.set_byte_length(byte_length.value()); - // 16. Set O.[[ByteOffset]] to 0. + // 14. Set O.[[ByteOffset]] to 0. dest_array.set_byte_offset(0); - // 17. Set O.[[ArrayLength]] to elementLength. + // 15. Set O.[[ArrayLength]] to elementLength. dest_array.set_array_length(element_length); - // 18. Return unused. + // 16. Return unused. return {}; } diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp index d2621706fa..fd78a0f7fa 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp @@ -7,7 +7,6 @@ */ #include <LibJS/Runtime/AbstractOperations.h> -#include <LibJS/Runtime/ArrayBufferConstructor.h> #include <LibJS/Runtime/ArrayIterator.h> #include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/TypedArray.h> @@ -670,11 +669,10 @@ static ThrowCompletionOr<void> set_typed_array_from_typed_array(GlobalObject& gl // a. Let srcByteLength be source.[[ByteLength]]. auto source_byte_length = source.byte_length(); - // b. Set srcBuffer to ? CloneArrayBuffer(srcBuffer, srcByteOffset, srcByteLength, %ArrayBuffer%). - source_buffer = TRY(clone_array_buffer(global_object, *source_buffer, source_byte_offset, source_byte_length, *global_object.array_buffer_constructor())); - // c. NOTE: %ArrayBuffer% is used to clone srcBuffer because is it known to not have any observable side-effects. + // b. Set srcBuffer to ? CloneArrayBuffer(srcBuffer, srcByteOffset, srcByteLength). + source_buffer = TRY(clone_array_buffer(global_object, *source_buffer, source_byte_offset, source_byte_length)); - // d. Let srcByteIndex be 0. + // c. Let srcByteIndex be 0. source_byte_index = 0; } // 19. Else, let srcByteIndex be srcByteOffset. |