diff options
author | Obinna Ikeh <hikenike6@gmail.com> | 2022-06-27 21:55:41 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-06-29 13:36:54 +0100 |
commit | 4dbb2c2d44d26983ee7a08d9fe22df5f7188e794 (patch) | |
tree | 6e8b908abbfdca285a6b4dc9719ba0f76b44f818 /Userland | |
parent | ee9353702c4eea6edef76cd6c4288656d678d17c (diff) | |
download | serenity-4dbb2c2d44d26983ee7a08d9fe22df5f7188e794.zip |
LibJS: Add %TypedArray%.prototype.toSorted
This change implements typed array prototype toSorted function.
It also introduces two new TypedArray functions
Diffstat (limited to 'Userland')
4 files changed, 67 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp index e885748350..22e22da0db 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp @@ -347,6 +347,22 @@ ThrowCompletionOr<TypedArrayBase*> typed_array_create(GlobalObject& global_objec return &typed_array; } +// 1.2.1.1 TypedArrayCreateSameType ( exemplar, argumentList ) https://tc39.es/proposal-change-array-by-copy/#typedarray-create-same-type +ThrowCompletionOr<TypedArrayBase*> typed_array_create_same_type(GlobalObject& global_object, TypedArrayBase const& exemplar, MarkedVector<Value> arguments) +{ + // 1. Assert: exemplar is an Object that has [[TypedArrayName]] and [[ContentType]] internal slots. + // 2. Let constructor be the intrinsic object listed in column one of Table 63 (points to Table 72) for exemplar.[[TypedArrayName]]. + auto* constructor = (global_object.*exemplar.intrinsic_constructor())(); + + // 3. Let result be ? TypedArrayCreate(constructor, argumentList). + auto* result = TRY(typed_array_create(global_object, *constructor, move(arguments))); + + // 4. Assert: result has [[TypedArrayName]] and [[ContentType]] internal slots. + // 5. Assert: result.[[ContentType]] is exemplar.[[ContentType]]. + // 6. Return result. + return result; +} + // 1.2.2.1.2 CompareTypedArrayElements ( x, y, comparefn, buffer ), https://tc39.es/proposal-change-array-by-copy/#sec-comparetypedarrayelements ThrowCompletionOr<double> compare_typed_array_elements(GlobalObject& global_object, Value x, Value y, FunctionObject* comparefn, ArrayBuffer& buffer) { diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.h b/Userland/Libraries/LibJS/Runtime/TypedArray.h index 839482fc54..515267119d 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.h +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.h @@ -451,6 +451,7 @@ private: }; ThrowCompletionOr<TypedArrayBase*> typed_array_create(GlobalObject& global_object, FunctionObject& constructor, MarkedVector<Value> arguments); +ThrowCompletionOr<TypedArrayBase*> typed_array_create_same_type(GlobalObject& global_object, TypedArrayBase const& exemplar, MarkedVector<Value> arguments); ThrowCompletionOr<double> compare_typed_array_elements(GlobalObject& global_object, Value x, Value y, FunctionObject* comparefn, ArrayBuffer&); #define JS_DECLARE_TYPED_ARRAY(ClassName, snake_name, PrototypeName, ConstructorName, Type) \ diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp index 1a616ba434..7348f7cae8 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp @@ -7,6 +7,7 @@ */ #include <LibJS/Runtime/AbstractOperations.h> +#include <LibJS/Runtime/Array.h> #include <LibJS/Runtime/ArrayIterator.h> #include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/TypedArray.h> @@ -56,6 +57,7 @@ void TypedArrayPrototype::initialize(GlobalObject& object) define_native_function(vm.names.filter, filter, 1, attr); define_native_function(vm.names.map, map, 1, attr); define_native_function(vm.names.toLocaleString, to_locale_string, 0, attr); + define_native_function(vm.names.toSorted, to_sorted, 1, attr); define_native_accessor(*vm.well_known_symbol_to_string_tag(), to_string_tag_getter, nullptr, Attribute::Configurable); @@ -1510,4 +1512,51 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_locale_string) return js_string(vm, builder.to_string()); } +// 1.2.2.1.4 %TypedArray%.prototype.toSorted ( comparefn ) https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.toSorted +JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_sorted) +{ + auto comparefn = vm.argument(0); + // 1. If comparefn is not undefined and IsCallable(comparefn) is false, throw a TypeError exception. + if (!comparefn.is_undefined() && !comparefn.is_function()) + return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, comparefn); + + // 2. Let O be the this value. + auto* object = TRY(vm.this_value(global_object).to_object(global_object)); + + // 3. Perform ? ValidateTypedArray(O). + auto* typed_array = TRY(validate_typed_array_from_this(global_object)); + + // 4. Let buffer be obj.[[ViewedArrayBuffer]]. + auto* array_buffer = typed_array->viewed_array_buffer(); + VERIFY(array_buffer); + + // 5. Let len be O.[[ArrayLength]]. + auto length = typed_array->array_length(); + + // 6. Let A be ? TypedArrayCreateSameType(O, ยซ ๐ฝ(len) ยป). + MarkedVector<Value> arguments(vm.heap()); + arguments.empend(length); + auto* return_array = TRY(typed_array_create_same_type(global_object, *typed_array, move(arguments))); + + // 7. NOTE: The following closure performs a numeric comparison rather than the string comparison used in Array.prototype.toSorted + // 8. Let SortCompare be a new Abstract Closure with parameters (x, y) that captures comparefn and buffer and performs the following steps when called: + Function<ThrowCompletionOr<double>(Value, Value)> sort_compare = [&](auto x, auto y) -> ThrowCompletionOr<double> { + // a. Return ? CompareTypedArrayElements(x, y, comparefn, buffer). + return TRY(compare_typed_array_elements(global_object, x, y, comparefn.is_undefined() ? nullptr : &comparefn.as_function(), *return_array->viewed_array_buffer())); + }; + + // 9. Let sortedList be ? SortIndexedProperties(obj, len, SortCompare, false). + auto sorted_list = TRY(sort_indexed_properties(global_object, *object, length, sort_compare, false)); + + // 10. Let j be 0. + // 11. Repeat, while j < len, + for (size_t j = 0; j < length; j++) { + // Perform ! Set(A, ! ToString(๐ฝ(j)), sortedList[j], true). + MUST(return_array->create_data_property_or_throw(j, sorted_list[j])); + // b. Set j to j + 1. + } + + return return_array; +} + } diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h index 7e706b8765..5e05055de4 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h +++ b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.h @@ -52,6 +52,7 @@ private: JS_DECLARE_NATIVE_FUNCTION(filter); JS_DECLARE_NATIVE_FUNCTION(map); JS_DECLARE_NATIVE_FUNCTION(to_locale_string); + JS_DECLARE_NATIVE_FUNCTION(to_sorted); }; } |